24395
732
Τα βιβλία προγραμματισμού γλωσσών εξηγούν ότι οι τύποι τιμών δημιουργούνται στη στοίβα και οι τύποι αναφοράς δημιουργούνται στο σωρό, χωρίς να εξηγείται ποια είναι αυτά τα δύο πράγματα. Δεν έχω διαβάσει μια σαφή εξήγηση για αυτό. Καταλαβαίνω τι είναι μια στοίβα. Αλλά,
Πού και τι είναι (φυσικά στη μνήμη ενός πραγματικού υπολογιστή);
Σε ποιο βαθμό ελέγχονται από το λειτουργικό σύστημα ή τον χρόνο εκτέλεσης της γλώσσας;
Ποιο είναι το πεδίο εφαρμογής τους;
Τι καθορίζει το μέγεθος καθενός από αυτά;
Τι κάνει πιο γρήγορο; 
Η στοίβα είναι η μνήμη που διατίθεται ως χώρος μηδέν για ένα νήμα εκτέλεσης. Όταν καλείται μια συνάρτηση, ένα μπλοκ δεσμεύεται στην κορυφή της στοίβας για τοπικές μεταβλητές και ορισμένα δεδομένα τήρησης βιβλίων. Όταν επιστρέψει αυτή η συνάρτηση, το μπλοκ δεν χρησιμοποιείται και μπορεί να χρησιμοποιηθεί την επόμενη φορά που καλείται μια συνάρτηση. Η στοίβα διατηρείται πάντα σε σειρά LIFO (τελευταία στην πρώτη έξοδο). το πιο πρόσφατα δεσμευμένο μπλοκ είναι πάντα το επόμενο μπλοκ που θα απελευθερωθεί. Αυτό το καθιστά πολύ απλό να παρακολουθείτε τη στοίβα. Η απελευθέρωση ενός μπλοκ από τη στοίβα δεν είναι τίποτα περισσότερο από τη ρύθμιση ενός δείκτη.
Ο σωρός είναι μνήμη που διατίθεται για δυναμική κατανομή. Σε αντίθεση με τη στοίβα, δεν υπάρχει επιβεβλημένο μοτίβο για την κατανομή και την αφαίρεση των μπλοκ από το σωρό. μπορείτε να εκχωρήσετε ένα μπλοκ ανά πάσα στιγμή και να το ελευθερώσετε ανά πάσα στιγμή. Αυτό καθιστά πολύ πιο περίπλοκο να παρακολουθείτε ποια μέρη του σωρού κατανέμονται ή να είναι δωρεάν ανά πάσα στιγμή. Υπάρχουν πολλοί προσαρμοσμένοι κατανεμητές σωρών για να συντονίσετε την απόδοση σωρού για διαφορετικά μοτίβα χρήσης.
Κάθε νήμα παίρνει μια στοίβα, ενώ συνήθως υπάρχει μόνο ένας σωρός για την εφαρμογή (αν και δεν είναι ασυνήθιστο να υπάρχουν πολλοί σωροί για διαφορετικούς τύπους κατανομής).
Για να απαντήσετε απευθείας στις ερωτήσεις σας:
Σε ποιο βαθμό ελέγχονται από το λειτουργικό σύστημα ή το χρόνο εκτέλεσης της γλώσσας;
Το λειτουργικό σύστημα εκχωρεί τη στοίβα για κάθε νήμα επιπέδου συστήματος κατά τη δημιουργία του νήματος. Συνήθως, το λειτουργικό σύστημα καλείται από τον χρόνο εκτέλεσης της γλώσσας για να εκχωρήσει το σωρό για την εφαρμογή.
Ποιο είναι το πεδίο εφαρμογής τους;
Η στοίβα είναι προσαρτημένη σε ένα νήμα, οπότε όταν το νήμα βγαίνει, η στοίβα ανακτάται. Ο σωρός κατανέμεται συνήθως κατά την εκκίνηση της εφαρμογής μέχρι το χρόνο εκτέλεσης και ανακτάται όταν τερματιστεί η εφαρμογή (τεχνικά διεργασία).
Τι καθορίζει το μέγεθος καθενός από αυτά;
Το μέγεθος της στοίβας ορίζεται όταν δημιουργείται ένα νήμα. Το μέγεθος του σωρού έχει οριστεί κατά την εκκίνηση της εφαρμογής, αλλά μπορεί να αυξηθεί καθώς απαιτείται χώρος (ο εκχωρητής ζητά περισσότερη μνήμη από το λειτουργικό σύστημα).
Τι κάνει πιο γρήγορο;
Η στοίβα είναι ταχύτερη επειδή το μοτίβο πρόσβασης το καθιστά ασήμαντο να εκχωρεί και να αφαιρεί τη μνήμη από αυτό (ένας δείκτης / ακέραιος απλώς αυξάνεται ή μειώνεται), ενώ ο σωρός έχει πολύ πιο περίπλοκη λογιστική που εμπλέκεται σε μια κατανομή ή αφαίρεση. Επίσης, κάθε byte στη στοίβα τείνει να επαναχρησιμοποιείται πολύ συχνά, πράγμα που σημαίνει ότι τείνει να αντιστοιχιστεί στην προσωρινή μνήμη του επεξεργαστή, καθιστώντας το πολύ γρήγορο. Ένα άλλο χτύπημα απόδοσης για το σωρό είναι ότι ο σωρός, ως επί το πλείστον ένας παγκόσμιος πόρος, πρέπει συνήθως να είναι ασφαλής πολλαπλών σπειρωμάτων, δηλαδή κάθε κατανομή και αφαίρεση πρέπει να είναι - τυπικά - συγχρονισμένος με "όλες" άλλες προσβάσεις σωρού στο πρόγραμμα.
Μια σαφής επίδειξη:
Πηγή εικόνας: vikashazrati.wordpress.com
|
Σωρός:
Αποθηκεύτηκε στη μνήμη RAM του υπολογιστή όπως και ο σωρός.
Οι μεταβλητές που δημιουργούνται στη στοίβα δεν θα καλύπτονται και θα καταργούνται αυτόματα.
Πολύ πιο γρήγορα για κατανομή σε σύγκριση με μεταβλητές στο σωρό.
Εφαρμόζεται με μια πραγματική δομή δεδομένων στοίβας.
Αποθηκεύει τοπικά δεδομένα, διευθύνσεις επιστροφής, που χρησιμοποιούνται για τη διαβίβαση παραμέτρων.
Μπορεί να έχει υπερχείλιση στοίβας όταν χρησιμοποιείται πολύ μεγάλο μέρος της στοίβας (κυρίως από άπειρη ή πολύ βαθιά αναδρομή, πολύ μεγάλες κατανομές).
Τα δεδομένα που δημιουργούνται στη στοίβα μπορούν να χρησιμοποιηθούν χωρίς δείκτες.
Θα χρησιμοποιούσατε τη στοίβα εάν γνωρίζετε ακριβώς πόσα δεδομένα πρέπει να διαθέσετε πριν από τη μεταγλώττιση και δεν είναι πολύ μεγάλο.
Συνήθως έχει ήδη καθοριστεί ένα μέγιστο μέγεθος κατά την έναρξη του προγράμματος.
Σωρός:
Αποθηκεύτηκε στη μνήμη RAM του υπολογιστή όπως και η στοίβα.
Στο C ++, οι μεταβλητές στο σωρό πρέπει να καταστρέφονται χειροκίνητα και να μην πέφτουν ποτέ εκτός πεδίου. Τα δεδομένα απελευθερώνονται με διαγραφή, διαγραφή [] ή δωρεάν.
Αργότερη κατανομή σε σύγκριση με μεταβλητές στη στοίβα.
Χρησιμοποιείται κατ 'απαίτηση για εκχώρηση ενός μπλοκ δεδομένων για χρήση από το πρόγραμμα.
Μπορεί να έχει κατακερματισμό όταν υπάρχουν πολλές κατανομές και καταργήσεις.
Στο C ++ ή C, τα δεδομένα που δημιουργούνται στο σωρό θα επισημαίνονται από δείκτες και θα κατανέμονται με νέο ή malloc αντίστοιχα.
Μπορεί να έχει αποτυχίες κατανομής εάν ζητηθεί να εκχωρηθεί πολύ μεγάλο από ένα buffer.
Θα χρησιμοποιούσατε το σωρό εάν δεν γνωρίζετε ακριβώς πόσα δεδομένα θα χρειαστείτε κατά το χρόνο εκτέλεσης ή εάν πρέπει να διαθέσετε πολλά δεδομένα.
Υπεύθυνος για διαρροές μνήμης.
Παράδειγμα:
int foo ()
{
char * pBuffer; // <- δεν έχει διατεθεί ακόμη τίποτα (εκτός από τον ίδιο τον δείκτη, ο οποίος κατανέμεται εδώ στη στοίβα).
bool b = αλήθεια; // Κατανεμήθηκε στη στοίβα.
εάν (β)
{
// Δημιουργήστε 500 byte στη στοίβα
buffer char [500];
// Δημιουργήστε 500 bytes στο σωρό
pBuffer = νέο char [500];
} // <- το buffer απενεργοποιείται εδώ, το pBuffer δεν είναι
} // <--- Ωχ υπάρχει διαρροή μνήμης, θα έπρεπε να ονομάσω delete [] pBuffer;
|
Το πιο σημαντικό σημείο είναι ότι ο σωρός και η στοίβα είναι γενικοί όροι για τους τρόπους με τους οποίους μπορεί να εκχωρηθεί μνήμη. Μπορούν να εφαρμοστούν με πολλούς διαφορετικούς τρόπους και οι όροι ισχύουν για τις βασικές έννοιες.
Σε μια στοίβα αντικειμένων, τα αντικείμενα κάθονται το ένα πάνω από το άλλο με τη σειρά που τοποθετήθηκαν εκεί και μπορείτε να αφαιρέσετε μόνο την κορυφή(χωρίς να ανατραπεί το όλο θέμα).
Η απλότητα μιας στοίβας είναι ότι δεν χρειάζεται να διατηρείτε έναν πίνακα που περιέχει μια εγγραφή για κάθε ενότητα εκχωρημένης μνήμης. η μόνη πληροφορία κατάστασης που χρειάζεστε είναι ένας δείκτης στο τέλος της στοίβας. Για να εκχωρήσετε και να αφαιρέσετε, απλώς αυξάνετε και μειώστε τον συγκεκριμένο δείκτη. Σημείωση: μια στοίβα μπορεί μερικές φορές να εφαρμοστεί για να ξεκινήσει στην κορυφή ενός τμήματος της μνήμης και να επεκταθεί προς τα κάτω αντί να αναπτυχθεί προς τα πάνω.
Σε έναν σωρό, δεν υπάρχει συγκεκριμένη σειρά στον τρόπο τοποθέτησης των αντικειμένων. Μπορείτε να προσεγγίσετε και να καταργήσετε αντικείμενα με οποιαδήποτε σειρά, επειδή δεν υπάρχει σαφές "κορυφαίο" στοιχείο.
Η κατανομή σωρού απαιτεί τη διατήρηση πλήρους καταγραφής για το τι εκχωρείται η μνήμη και τι όχι, καθώς και κάποια γενική συντήρηση για τη μείωση του κατακερματισμού, βρείτε τμήματα συνεχόμενης μνήμης αρκετά μεγάλα για να ταιριάζουν στο απαιτούμενο μέγεθος και ούτω καθεξής. Η μνήμη μπορεί να αφαιρεθεί ανά πάσα στιγμή αφήνοντας ελεύθερο χώρο. Μερικές φορές ένας εκχωρητής μνήμης θα εκτελεί εργασίες συντήρησης, όπως ανασυγκρότηση της μνήμης μετακινώντας την εκχωρημένη μνήμη, ή συλλογή απορριμμάτων - εντοπισμός κατά το χρόνο εκτέλεσης όταν η μνήμη δεν είναι πλέον σε εμβέλεια και η αφαίρεσή της.
Αυτές οι εικόνες πρέπει να κάνουν αρκετά καλή δουλειά για να περιγράψουν τους δύο τρόπους κατανομής και απελευθέρωσης της μνήμης σε μια στοίβα και έναν σωρό. Ναι!
Σε ποιο βαθμό ελέγχονται από το λειτουργικό σύστημα ή το χρόνο εκτέλεσης της γλώσσας;
Όπως αναφέρθηκε, ο σωρός και η στοίβα είναι γενικοί όροι και μπορούν να εφαρμοστούν με πολλούς τρόπους. Τα προγράμματα υπολογιστών έχουν συνήθως μια στοίβα που ονομάζεται στοίβα κλήσης, η οποία αποθηκεύει πληροφορίες σχετικές με την τρέχουσα συνάρτηση, όπως ένα δείκτη προς οποιαδήποτε συνάρτηση από την οποία κλήθηκε και τυχόν τοπικές μεταβλητές. Επειδή οι συναρτήσεις καλούν άλλες λειτουργίες και μετά επιστρέφουν, η στοίβα μεγαλώνει και συρρικνώνεται για να συγκρατεί τις πληροφορίες από τις συναρτήσεις κάτω από τη στοίβα κλήσεων. Ένα πρόγραμμα δεν έχει πραγματικά έλεγχο χρόνου εκτέλεσης. καθορίζεται από τη γλώσσα προγραμματισμού, το λειτουργικό σύστημα και ακόμη και την αρχιτεκτονική του συστήματος.
Ένας σωρός είναι ένας γενικός όρος που χρησιμοποιείται για κάθε μνήμη που κατανέμεται δυναμικά και τυχαία. δηλαδή εκτός λειτουργίας. Η μνήμη εκχωρείται συνήθως από το λειτουργικό σύστημα, με την εφαρμογή να καλεί λειτουργίες API για να πραγματοποιήσει αυτήν την κατανομή. Απαιτείται ένα αρκετά μικρό ποσό για τη διαχείριση της δυναμικά εκχωρημένης μνήμης, η οποία συνήθως αντιμετωπίζεται από τον κώδικα χρόνου εκτέλεσης της γλώσσας προγραμματισμού ή του περιβάλλοντος που χρησιμοποιείται.
Ποιο είναι το πεδίο εφαρμογής τους;
Η στοίβα κλήσεων είναι μια έννοια χαμηλού επιπέδου που δεν σχετίζεται με το «πεδίο» υπό την έννοια του προγραμματισμού. Εάν αποσυναρμολογήσετε κάποιο κώδικα, θα δείτε σχετικές αναφορές στυλ δείκτη σε τμήματα της στοίβας, αλλά όσον αφορά μια γλώσσα υψηλότερου επιπέδου, η γλώσσα επιβάλλει τους δικούς της κανόνες εφαρμογής. Μια σημαντική πτυχή μιας στοίβας, ωστόσο, είναι ότι μόλις επιστρέψει μια συνάρτηση, οτιδήποτε τοπικό σε αυτήν τη λειτουργία απελευθερώνεται αμέσως από τη στοίβα. Λειτουργεί με τον τρόπο που θα περίμενε κανείς να λειτουργεί δεδομένου του τρόπου λειτουργίας των γλωσσών προγραμματισμού Σε έναν σωρό, είναι επίσης δύσκολο να οριστεί. Το εύρος είναι ό, τι εκτίθεται από το λειτουργικό σύστημα, αλλά η γλώσσα προγραμματισμού σας πιθανότατα προσθέτει τους κανόνες του σχετικά με το τι είναι "εύρος" στην εφαρμογή σας. Η αρχιτεκτονική του επεξεργαστή και το λειτουργικό σύστημα χρησιμοποιούν εικονικές διευθύνσεις, τις οποίες ο επεξεργαστής μεταφράζει σε φυσικές διευθύνσεις και υπάρχουν σφάλματα σελίδας κ.λπ. Παρακολουθούν ποιες σελίδες ανήκουν σε ποιες εφαρμογές. Δεν χρειάζεται ποτέ να ανησυχείτε γι 'αυτό, διότι απλώς χρησιμοποιείτε οποιαδήποτε μέθοδο χρησιμοποιεί η γλώσσα προγραμματισμού για να εκχωρήσετε και να ελευθερώσετε μνήμη και να ελέγξετε για σφάλματα (εάν η κατανομή / απελευθέρωση αποτύχει για οποιονδήποτε λόγο).
Τι καθορίζει το μέγεθος καθενός από αυτά;
Και πάλι, εξαρτάται από τη γλώσσα, τον μεταγλωττιστή, το λειτουργικό σύστημα και την αρχιτεκτονική. Μια στοίβα συνήθως εκχωρείται εκ των προτέρων, επειδή εξ ορισμού πρέπει να είναι συνεχόμενη μνήμη. Ο μεταγλωττιστής γλώσσας ή το λειτουργικό σύστημα καθορίζουν το μέγεθός του. Δεν αποθηκεύετε τεράστια κομμάτια δεδομένων στη στοίβα, οπότε θα είναι αρκετά μεγάλο ώστε ποτέ να μην χρησιμοποιείται πλήρως, εκτός από περιπτώσεις ανεπιθύμητης ατελείωτης επανάληψης (ως εκ τούτου, "υπερχείλιση στοίβας") ή άλλες ασυνήθιστες αποφάσεις προγραμματισμού.
Ένας σωρός είναι ένας γενικός όρος για οτιδήποτε μπορεί να εκχωρηθεί δυναμικά. Ανάλογα με τον τρόπο που το κοιτάζετε, αλλάζει συνεχώς το μέγεθος. Στους σύγχρονους επεξεργαστές και λειτουργικά συστήματα, ο ακριβής τρόπος που λειτουργεί είναι πολύ αφαιρεθεί ούτως ή άλλως, οπότε δεν χρειάζεται να ανησυχείτε πολύ για το πώς λειτουργεί βαθιά, εκτός από το ότι (σε ​​γλώσσες όπου σας επιτρέπει) δεν πρέπει να χρησιμοποιείτε δεν έχετε εκχωρήσει ακόμη ή μνήμη που έχετε ελευθερώσει.
Τι κάνει πιο γρήγορο;
Η στοίβα είναι ταχύτερη επειδή όλη η ελεύθερη μνήμη είναι πάντα συνεχόμενη. Δεν χρειάζεται να διατηρηθεί λίστα όλων των τμημάτων της ελεύθερης μνήμης, μόνο ένας δείκτης στην τρέχουσα κορυφή της στοίβας. Οι μεταγλωττιστές συνήθως αποθηκεύουν αυτόν τον δείκτη σε έναν ειδικό, γρήγορο καταχωρητή για το σκοπό αυτό. Επιπλέον, οι επόμενες λειτουργίες σε μια στοίβα συνήθως συγκεντρώνονται σε πολύ κοντινές περιοχές της μνήμης, η οποία σε πολύ χαμηλό επίπεδο είναι καλή για βελτιστοποίηση από τον επεξεργαστή κατά τη διάρκειακρυφές μνήμες.
|
(Έχω μετακινήσει αυτήν την απάντηση από μια άλλη ερώτηση που ήταν λίγο πολύ μια απάντηση.)
Η απάντηση στην ερώτησή σας είναι συγκεκριμένη εφαρμογή και μπορεί να διαφέρει ανάλογα με τις μεταγλωττιστές και τις αρχιτεκτονικές επεξεργαστών. Ωστόσο, εδώ είναι μια απλοποιημένη εξήγηση.
Τόσο η στοίβα όσο και ο σωρός είναι περιοχές μνήμης που κατανέμονται από το υποκείμενο λειτουργικό σύστημα (συχνά εικονική μνήμη που αντιστοιχίζεται στη φυσική μνήμη κατά παραγγελία).
Σε ένα περιβάλλον πολλαπλών νημάτων, κάθε νήμα θα έχει τη δική του εντελώς ανεξάρτητη στοίβα, αλλά θα μοιράζεται το σωρό. Η ταυτόχρονη πρόσβαση πρέπει να ελέγχεται στο σωρό και δεν είναι δυνατή στη στοίβα.
Ο σωρός
Ο σωρός περιέχει μια συνδεδεμένη λίστα μεταχειρισμένων και δωρεάν μπλοκ. Οι νέες κατανομές στο σωρό (από νέο ή malloc) ικανοποιούνται δημιουργώντας ένα κατάλληλο μπλοκ από ένα από τα δωρεάν μπλοκ. Αυτό απαιτεί ενημέρωση της λίστας μπλοκ στο σωρό. Αυτές οι μετα-πληροφορίες σχετικά με τα μπλοκ στο σωρό αποθηκεύονται επίσης στο σωρό συχνά σε μια μικρή περιοχή ακριβώς μπροστά από κάθε μπλοκ.
Καθώς ο σωρός μεγαλώνει, νέα μπλοκ κατανέμονται συχνά από χαμηλότερες διευθύνσεις σε υψηλότερες διευθύνσεις. Έτσι μπορείτε να σκεφτείτε το σωρό ως σωρό μπλοκ μνήμης που μεγαλώνει σε μέγεθος καθώς κατανέμεται η μνήμη. Εάν ο σωρός είναι πολύ μικρός για κατανομή, το μέγεθος μπορεί συχνά να αυξηθεί αποκτώντας περισσότερη μνήμη από το υποκείμενο λειτουργικό σύστημα.
Η κατανομή και η αφαίρεση πολλών μικρών μπλοκ μπορεί να αφήσει το σωρό σε μια κατάσταση όπου υπάρχουν πολλά μικρά ελεύθερα μπλοκ που διασχίζονται μεταξύ των χρησιμοποιημένων μπλοκ. Ένα αίτημα εκχώρησης ενός μεγάλου μπλοκ ενδέχεται να αποτύχει επειδή κανένα από τα ελεύθερα μπλοκ δεν είναι αρκετά μεγάλο για να ικανοποιήσει το αίτημα κατανομής παρόλο που το συνδυασμένο μέγεθος των ελεύθερων μπλοκ μπορεί να είναι αρκετά μεγάλο. Αυτό ονομάζεται κατακερματισμός σωρού.
Όταν ένα χρησιμοποιημένο μπλοκ που είναι δίπλα σε ένα ελεύθερο μπλοκ αφαιρεθεί, το νέο ελεύθερο μπλοκ μπορεί να συγχωνευθεί με το παρακείμενο ελεύθερο μπλοκ για να δημιουργήσει ένα μεγαλύτερο ελεύθερο μπλοκ μειώνοντας αποτελεσματικά τον κατακερματισμό του σωρού.
Η στοίβα
Η στοίβα λειτουργεί συχνά σε στενή σύνδεση με έναν ειδικό καταχωρητή στη CPU που ονομάζεται δείκτης στοίβας. Αρχικά ο δείκτης στοίβας δείχνει στην κορυφή της στοίβας (η υψηλότερη διεύθυνση στη στοίβα).
Η CPU έχει ειδικές οδηγίες για την ώθηση των τιμών στη στοίβα και την επιστροφή τους από τη στοίβα. Κάθε ώθηση αποθηκεύει την τιμή στην τρέχουσα θέση του δείκτη στοίβας και μειώνει το δείκτη στοίβας. Ένα pop ανακτά την τιμή που δείχνει ο δείκτης στοίβας και στη συνέχεια αυξάνει το δείκτη στοίβας (μην μπερδεύεστε από το γεγονός ότι η προσθήκη μιας τιμής στη στοίβα μειώνει το δείκτη στοίβας και η αφαίρεση μιας τιμής αυξάνει. Να θυμάστε ότι η στοίβα μεγαλώνει σε ο πάτος). Οι τιμές που αποθηκεύονται και ανακτώνται είναι οι τιμές των καταχωρητών CPU.
Όταν καλείται μια συνάρτηση, η CPU χρησιμοποιεί ειδικές οδηγίες που ωθούν τον τρέχοντα δείκτη εντολών, δηλαδή τη διεύθυνση του κώδικα που εκτελείται στη στοίβα. Στη συνέχεια, η CPU μεταβαίνει στη λειτουργία ρυθμίζοντας το
δείκτης εντολής στη διεύθυνση της λειτουργίας που καλείται. Αργότερα, όταν επιστρέψει η συνάρτηση, ο παλιός δείκτης εντολών αναδύεται από τη στοίβα και η εκτέλεση συνεχίζεται στον κώδικα αμέσως μετά την κλήση στη συνάρτηση.
Όταν εισαχθεί μια συνάρτηση, ο δείκτης στοίβας μειώνεται για να εκχωρήσει περισσότερο χώρο στη στοίβα για τοπικές (αυτόματες) μεταβλητές. Εάν η συνάρτηση έχει μια τοπική μεταβλητή 32 bit, τέσσερα byte διατίθενται στη στοίβα. Όταν επιστρέψει η συνάρτηση, ο δείκτης στοίβας μετακινείται πίσω για να ελευθερώσει την εκχωρημένη περιοχή.
Εάν μια συνάρτηση έχει παραμέτρους, αυτές ωθούνται στη στοίβα πριν από την κλήση στη συνάρτηση. Ο κώδικας στη συνάρτηση είναι στη συνέχεια σε θέση να πλοηγηθεί επάνω στη στοίβα από τον τρέχοντα δείκτη στοίβας για να εντοπίσει αυτές τις τιμές.
Οι κλήσεις λειτουργιών ένθεσης λειτουργούν σαν γοητεία. Κάθε νέα κλήση θα κατανέμει παραμέτρους λειτουργίας, τη διεύθυνση επιστροφής και το χώρο για τοπικές μεταβλητές και αυτές οι εγγραφές ενεργοποίησης μπορούν να στοιβάζονται για ένθετες κλήσεις και θα ξεκουραστούν με τον σωστό τρόπο κατά την επιστροφή των λειτουργιών.
Καθώς η στοίβα είναι ένα περιορισμένο μπλοκ μνήμης, μπορείτε να προκαλέσετε υπερχείλιση στοίβας καλώντας πάρα πολλές ένθετες συναρτήσεις ή / και εκχωρώντας πολύ χώρο για τοπικές μεταβλητές. Συχνά η περιοχή μνήμης που χρησιμοποιείται για τη στοίβα έχει ρυθμιστεί με τέτοιο τρόπο ώστε η εγγραφή κάτω από το κάτω μέρος (η χαμηλότερη διεύθυνση) της στοίβας να προκαλέσει παγίδα ή εξαίρεση στη CPU. Αυτή η εξαιρετική κατάσταση μπορεί στη συνέχεια να πιάσει τον χρόνο εκτέλεσης και να μετατραπεί σε κάποιο είδος εξαίρεσης στοίβας υπερχείλισης.
Μπορεί να εκχωρηθεί μια συνάρτηση στο σωρό αντί για μια στοίβα;
Όχι, οι εγγραφές ενεργοποίησης για συναρτήσεις (δηλαδή τοπικές ή αυτόματες μεταβλητές) κατανέμονται στη στοίβα που χρησιμοποιείται όχι μόνο για την αποθήκευση αυτών των μεταβλητών, αλλά και για την παρακολούθηση των ένθετων κλήσεων λειτουργίας.
Ο τρόπος διαχείρισης του σωρού εξαρτάται πραγματικά από το περιβάλλον χρόνου εκτέλεσης. Το C χρησιμοποιεί malloc και το C ++ χρησιμοποιεί νέα, αλλά πολλές άλλες γλώσσες έχουν συλλογή απορριμμάτων.
Ωστόσο, η στοίβα είναι ένα χαρακτηριστικό χαμηλότερου επιπέδου που συνδέεται στενά με την αρχιτεκτονική του επεξεργαστή. Η ανάπτυξη του σωρού όταν δεν υπάρχει αρκετός χώρος δεν είναι πολύ δύσκολη από τότεΜπορεί να εφαρμοστεί στην κλήση βιβλιοθήκης που χειρίζεται το σωρό. Ωστόσο, η ανάπτυξη της στοίβας είναι συχνά αδύνατη καθώς η υπερχείλιση στοίβας ανακαλύπτεται μόνο όταν είναι πολύ αργά. και το κλείσιμο του νήματος εκτέλεσης είναι η μόνη βιώσιμη επιλογή.
|
Στον ακόλουθο κωδικό C #
δημόσιο κενό Μέθοδος 1 ()
{
int i = 4;
int y = 2;
class1 cls1 = νέο class1 ();
}
Δείτε πώς διαχειρίζεται η μνήμη
Τοπικές μεταβλητές που πρέπει να διαρκέσουν μόνο εφόσον η επίκληση της συνάρτησης πηγαίνει στη στοίβα. Ο σωρός χρησιμοποιείται για μεταβλητές των οποίων η διάρκεια ζωής δεν γνωρίζουμε πραγματικά μπροστά, αλλά περιμένουμε να διαρκέσουν λίγο. Στις περισσότερες γλώσσες είναι κρίσιμο να γνωρίζουμε τη στιγμή της μεταγλώττισης πόσο μεγάλη είναι μια μεταβλητή εάν θέλουμε να την αποθηκεύσουμε στη στοίβα.
Τα αντικείμενα (τα οποία ποικίλλουν σε μέγεθος καθώς τα ενημερώνουμε) πηγαίνουν στο σωρό επειδή δεν γνωρίζουμε τη στιγμή της δημιουργίας πόσο θα διαρκέσουν. Σε πολλές γλώσσες, ο σωρός συλλέγεται σκουπίδια για την εύρεση αντικειμένων (όπως το αντικείμενο cls1) που δεν έχουν πλέον καμία αναφορά.
Στην Java, τα περισσότερα αντικείμενα πηγαίνουν κατευθείαν στο σωρό. Σε γλώσσες όπως το C / C ++, οι δομές και οι τάξεις μπορούν συχνά να παραμείνουν στη στοίβα όταν δεν ασχολείστε με δείκτες.
Περισσότερες πληροφορίες μπορείτε να βρείτε εδώ:
Η διαφορά μεταξύ κατανομής μνήμης στοίβας και σωρού «timmurphy.org
και εδώ:
Δημιουργία αντικειμένων στη στοίβα και στο σωρό
Αυτό το άρθρο είναι η πηγή της παραπάνω εικόνας: Έξι σημαντικές έννοιες .NET: Στοίβα, σωρός, τύποι τιμών, τύποι αναφοράς, πυγμαχία και αποσυμπίεση - CodeProject
αλλά να γνωρίζετε ότι μπορεί να περιέχει ορισμένες ανακρίβειες.
|
Η στοίβα
Όταν καλείτε μια συνάρτηση, τα ορίσματα σε αυτήν τη συνάρτηση καθώς και κάποια άλλα γενικά τοποθετούνται στη στοίβα. Ορισμένες πληροφορίες (όπως το πού να επιστρέψετε) αποθηκεύονται επίσης εκεί.
Όταν δηλώνετε μια μεταβλητή μέσα στη λειτουργία σας, αυτή η μεταβλητή κατανέμεται επίσης στη στοίβα.
Η απενεργοποίηση της στοίβας είναι πολύ απλή, επειδή πάντα απενεργοποιείτε με την αντίστροφη σειρά με την οποία εκχωρείτε. Στοίβα πράγματα προστίθενται καθώς εισάγετε συναρτήσεις, τα αντίστοιχα δεδομένα αφαιρούνται καθώς τα βγείτε. Αυτό σημαίνει ότι έχετε την τάση να παραμένετε σε μια μικρή περιοχή της στοίβας, εκτός εάν καλέσετε πολλές συναρτήσεις που καλούν πολλές άλλες λειτουργίες (ή δημιουργήσετε μια αναδρομική λύση).
Ο σωρός
Το σωρό είναι ένα γενικό όνομα για το πού βάζετε τα δεδομένα που δημιουργείτε. Εάν δεν γνωρίζετε πόσα διαστημόπλοια πρόκειται να δημιουργήσει το πρόγραμμά σας, είναι πιθανό να χρησιμοποιήσετε το νέο (ή malloc ή ισοδύναμο) χειριστή για να δημιουργήσετε κάθε διαστημόπλοιο. Αυτή η κατανομή πρόκειται να παραμείνει για λίγο, οπότε είναι πιθανό να απελευθερώσουμε τα πράγματα με διαφορετική σειρά από αυτά που τα δημιουργήσαμε.
Έτσι, ο σωρός είναι πολύ πιο περίπλοκος, επειδή καταλήγουν να υπάρχουν περιοχές μνήμης που δεν χρησιμοποιούνται παρεμβαλλόμενες με κομμάτια που είναι - η μνήμη γίνεται κατακερματισμένη. Η εύρεση ελεύθερης μνήμης του μεγέθους που χρειάζεστε είναι ένα δύσκολο πρόβλημα. Αυτός είναι ο λόγος για τον οποίο ο σωρός πρέπει να αποφεύγεται (αν και εξακολουθεί να χρησιμοποιείται συχνά).
Εκτέλεση
Η εφαρμογή τόσο της στοίβας όσο και του σωρού είναι συνήθως κάτω από το χρόνο εκτέλεσης / OS. Συχνά τα παιχνίδια και άλλες εφαρμογές που είναι κρίσιμες για την απόδοση δημιουργούν τις δικές τους λύσεις μνήμης που αρπάζουν ένα μεγάλο κομμάτι μνήμης από το σωρό και στη συνέχεια το τοποθετούν εσωτερικά για να αποφύγουν να βασίζονται στο λειτουργικό σύστημα για τη μνήμη.
Αυτό είναι πρακτικό μόνο εάν η χρήση της μνήμης σας είναι πολύ διαφορετική από τον κανόνα - δηλαδή για παιχνίδια όπου φορτώνετε ένα επίπεδο σε μια τεράστια λειτουργία και μπορείτε να τσακίσετε ολόκληρη την παρτίδα σε μια άλλη τεράστια λειτουργία.
Φυσική θέση στη μνήμη
Αυτό είναι λιγότερο σχετικό από ό, τι νομίζετε, λόγω μιας τεχνολογίας που ονομάζεται Virtual Memory, η οποία κάνει το πρόγραμμά σας να πιστεύει ότι έχετε πρόσβαση σε μια συγκεκριμένη διεύθυνση όπου τα φυσικά δεδομένα βρίσκονται κάπου αλλού (ακόμη και στον σκληρό δίσκο!). Οι διευθύνσεις που λαμβάνετε για τη στοίβα είναι σε αυξανόμενη σειρά καθώς το δέντρο κλήσεών σας γίνεται βαθύτερο. Οι διευθύνσεις για το σωρό δεν είναι προβλέψιμες (δηλ. Συγκεκριμένες εφαρμογές) και ειλικρινά δεν είναι σημαντικές.
|
Για να διευκρινιστεί, αυτή η απάντηση έχει λανθασμένες πληροφορίες (ο thomas διόρθωσε την απάντησή του μετά από σχόλια, δροσερό :)). Άλλες απαντήσεις αποφεύγουν να εξηγήσουν τι σημαίνει στατική κατανομή. Θα εξηγήσω λοιπόν τις τρεις κύριες μορφές κατανομής και πώς σχετίζονται συνήθως με το τμήμα σωρού, στοίβας και δεδομένων παρακάτω. Θα δείξω επίσης μερικά παραδείγματα τόσο στο C / C ++ όσο και στο Python για να βοηθήσω τους ανθρώπους να καταλάβουν.
Οι "στατικές" (AKA στατικά κατανεμημένες) μεταβλητές δεν κατανέμονται στη στοίβα. Μην το υποθέτετε - πολλοί άνθρωποι το κάνουν μόνο επειδή το "στατικό" ακούγεται πολύ σαν "στοίβα". Στην πραγματικότητα δεν υπάρχουν ούτε στη στοίβα ούτε στο σωρό. Είναι μέρος αυτού που ονομάζεται τμήμα δεδομένων.
Ωστόσο, είναι γενικά καλύτερο να εξετάσουμε το "εύρος" και τη "διάρκεια ζωής" αντί να "στοίβα" και "σωρός".
Το πεδίο εφαρμογής αναφέρεται σε ποια μέρη του κώδικα μπορούν να έχουν πρόσβαση σε μια μεταβλητή. Γενικά, σκεφτόμαστε το τοπικό πεδίο (μπορεί να προσεγγιστεί μόνο η τρέχουσα συνάρτηση) έναντι του παγκόσμιου πεδίου (μπορεί να προσπελαστεί οπουδήποτε), αν και το πεδίο εφαρμογής μπορεί να γίνει πολύ πιο περίπλοκο.
Η διάρκεια ζωής αναφέρεται σε πότε μια μεταβλητή κατανέμεται και καταργείται κατά την εκτέλεση του προγράμματος. Συνήθως σκεφτόμαστε τη στατική κατανομή (μεταβλητήθα επιμείνει καθ 'όλη τη διάρκεια του προγράμματος, καθιστώντας το χρήσιμο για την αποθήκευση των ίδιων πληροφοριών σε πολλές κλήσεις λειτουργιών) έναντι της αυτόματης κατανομής (η μεταβλητή παραμένει μόνο κατά τη διάρκεια μίας μόνο κλήσης σε μια συνάρτηση, καθιστώντας τη χρήσιμη για την αποθήκευση πληροφοριών που χρησιμοποιούνται μόνο κατά τη λειτουργία και μπορεί να απορριφθεί μόλις τελειώσετε) έναντι δυναμικής κατανομής (μεταβλητές των οποίων η διάρκεια ορίζεται κατά το χρόνο εκτέλεσης, αντί για χρόνο μεταγλώττισης όπως στατικό ή αυτόματο).
Παρόλο που οι περισσότεροι μεταγλωττιστές και διερμηνείς εφαρμόζουν αυτήν τη συμπεριφορά με τον ίδιο τρόπο όσον αφορά τη χρήση στοίβας, σωρών κ.λπ., ένας μεταγλωττιστής μπορεί μερικές φορές να παραβιάσει αυτές τις συμβάσεις εάν το επιθυμεί, εφόσον η συμπεριφορά είναι σωστή. Για παράδειγμα, λόγω βελτιστοποίησης μια τοπική μεταβλητή μπορεί να υπάρχει μόνο σε ένα μητρώο ή να αφαιρεθεί εξ ολοκλήρου, παρόλο που οι περισσότερες τοπικές μεταβλητές υπάρχουν στη στοίβα. Όπως έχει επισημανθεί σε μερικά σχόλια, είστε ελεύθεροι να εφαρμόσετε έναν μεταγλωττιστή που δεν χρησιμοποιεί καν στοίβα ή σωρό, αλλά αντίθετα μερικούς άλλους μηχανισμούς αποθήκευσης (σπάνια γίνεται, καθώς οι στοίβες και οι σωροί είναι εξαιρετικοί για αυτό).
Θα παράσχω έναν απλό σχολιασμένο κώδικα C για να τα απεικονίσω όλα αυτά. Ο καλύτερος τρόπος για να μάθετε είναι να εκτελέσετε ένα πρόγραμμα κάτω από ένα πρόγραμμα εντοπισμού σφαλμάτων και να παρακολουθήσετε τη συμπεριφορά. Εάν προτιμάτε να διαβάσετε το python, μεταβείτε στο τέλος της απάντησης :)
// Διατίθεται στατικά στο τμήμα δεδομένων κατά την πρώτη φόρτωση του προγράμματος / DLL
// Απενεργοποιείται όταν τερματίζεται το πρόγραμμα / DLL
// εύρος - μπορεί να προσεγγιστεί από οπουδήποτε στον κώδικα
int someGlobalVariable;
// Διατίθεται στατικά στο τμήμα δεδομένων κατά την πρώτη φόρτωση του προγράμματος
// Απενεργοποιείται όταν τερματίζεται το πρόγραμμα / DLL
// πεδίο - μπορεί να προσεγγιστεί από οπουδήποτε σε αυτό το συγκεκριμένο αρχείο κώδικα
static int someStaticVariable;
// Το "someArgument" εκχωρείται στη στοίβα κάθε φορά που καλείται το MyFunction
// Το "someArgument" απενεργοποιείται κατά την επιστροφή του MyFunction
// εύρος - είναι δυνατή η πρόσβαση μόνο στο MyFunction ()
void MyFunction (int someArgument) {
// Διατίθεται στατικά στο τμήμα δεδομένων κατά την πρώτη φόρτωση του προγράμματος
// Καταργήθηκε κατά την έξοδο του προγράμματος / DLL
// εύρος - είναι δυνατή η πρόσβαση μόνο στο MyFunction ()
static int someLocalStaticVariable;
// Διατίθεται στη στοίβα κάθε φορά που καλείται το MyFunction
// Καταργήθηκε κατά την επιστροφή του MyFunction
// εύρος - είναι δυνατή η πρόσβαση μόνο στο MyFunction ()
int someLocalVariable;
// Ένας * δείκτης * εκχωρείται στη στοίβα κάθε φορά που καλείται το MyFunction
// Αυτός ο δείκτης απενεργοποιείται κατά την επιστροφή του MyFunction
// εύρος - η πρόσβαση του δείκτη γίνεται μόνο στο MyFunction ()
int * someDynamicVariable;
// Αυτή η γραμμή προκαλεί την κατανομή χώρου για έναν ακέραιο στο σωρό
// όταν εκτελείται αυτή η γραμμή. Σημειώστε ότι αυτό δεν είναι στην αρχή του
// η κλήση στο MyFunction (), όπως οι αυτόματες μεταβλητές
// εύρος - μόνο ο κωδικός στο MyFunction () μπορεί να έχει πρόσβαση σε αυτόν τον χώρο
// * μέσω αυτής της συγκεκριμένης μεταβλητής *.
// Ωστόσο, εάν δώσετε τη διεύθυνση κάπου αλλού, αυτός ο κωδικός
// μπορεί να έχει πρόσβαση και σε αυτό
someDynamicVariable = νέο int;
// Αυτή η γραμμή αφαιρεί το χώρο για τον ακέραιο στο σωρό.
// Εάν δεν το γράψαμε, η μνήμη θα "διαρρέει".
// Σημειώστε μια θεμελιώδη διαφορά μεταξύ της στοίβας και του σωρού
// ο σωρός πρέπει να διαχειριστεί. Η στοίβα διαχειρίζεται για εμάς.
διαγραφή κάποιουDynamicVariable;
// Σε άλλες περιπτώσεις, αντί να αφαιρέσετε αυτό το σωρό χώρο εσείς
// μπορεί να αποθηκεύσει τη διεύθυνση κάπου πιο μόνιμη για χρήση αργότερα.
// Ορισμένες γλώσσες φροντίζουν ακόμη και την εκκαθάριση για εσάς ... αλλά
// πάντα πρέπει να φροντίζεται κατά το χρόνο εκτέλεσης με κάποιο μηχανισμό
// Όταν επιστρέφει η συνάρτηση, someArgument, someLocalVariable
// και ο δείκτης someDynamicVariable καταργούνται.
// Ο χώρος που επεσήμανε το someDynamicVariable ήταν ήδη
// απενεργοποιήθηκε πριν από την επιστροφή.
ΕΠΙΣΤΡΟΦΗ;
}
// Σημειώστε ότι someGlobalVariable, someStaticVariable και
// someLocalStaticVariable εξακολουθούν να υπάρχουν και δεν είναι
// καταργήθηκε έως ότου τερματιστεί το πρόγραμμα.
Ένα ιδιαίτερα έντονο παράδειγμα του γιατί είναι σημαντικό να γίνει διάκριση μεταξύ διάρκειας ζωής και εύρους είναι ότι μια μεταβλητή μπορεί να έχει τοπικό εύρος αλλά στατική διάρκεια ζωής - για παράδειγμα, "someLocalStaticVariable" στο παραπάνω δείγμα κώδικα. Τέτοιες μεταβλητές μπορούν να κάνουν τις κοινές αλλά ανεπίσημες συνήθειες ονομασίας μας πολύ συγκεχυμένες. Για παράδειγμα, όταν λέμε "τοπικό", συνήθως εννοούμε "τοπικά μεταβλητή που εκχωρείται αυτόματα μεταβλητή" και όταν λέμε καθολικό εννοούμε συνήθως "παγκόσμια μεταβλητή με στατιστικά κατανεμημένη μεταβλητή" Δυστυχώς, όταν πρόκειται για πράγματα όπως το "file scoped statistic κατανέμεται μεταβλητές", πολλοί άνθρωποι απλά λένε ... "ε;
Ορισμένες από τις επιλογές σύνταξης στο C / C ++ επιδεινώνουν αυτό το πρόβλημα - για παράδειγμα πολλοί άνθρωποι πιστεύουν ότι οι καθολικές μεταβλητές δεν είναι "στατικές" λόγω της σύνταξης που φαίνεται παρακάτω.
int var1; // Έχει παγκόσμιο εύρος και στατική κατανομή
στατικό int var2; // Έχει πεδίο εφαρμογής και στατική κατανομή
int main () {επιστροφή 0;}
Σημειώστε ότι η τοποθέτηση της λέξης-κλειδιού "στατική" στην παραπάνω δήλωση αποτρέπει το var2 να έχει παγκόσμιο εύρος. Ωστόσο, το παγκόσμιο var1 έχει στατική κατανομή. Αυτό δεν είναιενστικτώδης! Για αυτόν τον λόγο, προσπαθώ να μην χρησιμοποιήσω ποτέ τη λέξη "στατική" όταν περιγράφω το εύρος και, αντίθετα, να πω κάτι σαν πεδίο "αρχείο" ή "περιορισμένο αρχείο". Ωστόσο, πολλοί άνθρωποι χρησιμοποιούν τη φράση "στατικό" ή "στατικό εύρος" για να περιγράψουν μια μεταβλητή στην οποία υπάρχει πρόσβαση μόνο από ένα αρχείο κώδικα. Στο πλαίσιο της διάρκειας ζωής, το "στατικό" σημαίνει πάντοτε ότι η μεταβλητή κατανέμεται κατά την έναρξη του προγράμματος και απενεργοποιείται όταν εξέρχεται το πρόγραμμα.
Μερικοί άνθρωποι θεωρούν αυτές τις έννοιες ως C / C ++ συγκεκριμένες. Δεν είναι. Για παράδειγμα, το παρακάτω δείγμα Python απεικονίζει και τους τρεις τύπους κατανομής (υπάρχουν κάποιες λεπτές διαφορές στις ερμηνευμένες γλώσσες που δεν θα μπω εδώ).
από ώρα εισαγωγής ημερομηνίας ώρας
τάξη ζώων:
_FavoriteFood = 'Undefined' # _FavoriteFood κατανέμεται στατικά
def PetAnimal (αυτο):
curTime = datetime.time (datetime.now ()) # curTime εκχωρείται αυτόματα
print ("Σας ευχαριστώ που με χάρατε. Αλλά είναι" + str (curTime) + ", θα πρέπει να με ταΐσετε. Το αγαπημένο μου φαγητό είναι" + self._FavoriteFood)
τάξη γάτα (ζώο):
_FavoriteFood = 'tuna' # Σημείωση από την παράκαμψη, η κατηγορία Cat έχει τη δική της στατική κατανομή _FavoriteFood μεταβλητή, διαφορετική από το Animal's
Σκύλος κατηγορίας (Ζώο):
_FavoriteFood = 'steak' # Ομοίως, η κατηγορία Dog έχει τη δική της στατική μεταβλητή. Είναι σημαντικό να σημειωθεί - αυτή η στατική μεταβλητή κοινοποιείται σε όλες τις περιπτώσεις του Dog, επομένως δεν είναι δυναμική!
αν __name__ == "__main__":
μουστάκια = Cat () # Δυναμικά εκχωρημένο
fido = Dog () # Δυναμικά κατανεμημένο
rinTinTin = Dog () # Κατανεμημένο δυναμικά
μουστάκια. κατοικίδιο ζώο ()
fido.PetAnimal ()
rinTinTin.PetAnimal ()
Dog._FavouriteFood = "γαλακτοκομικά"
μουστάκια. κατοικίδιο ζώο ()
fido.PetAnimal ()
rinTinTin.PetAnimal ()
# Η έξοδος είναι:
# Ευχαριστώ που με χάραξες. Αλλά είναι 13: 05: 02.255000, πρέπει να με ταΐσεις. Το αγαπημένο μου φαγητό είναι ο τόνος
# Ευχαριστώ που με χάραξες. Αλλά είναι 13: 05: 02.255000, πρέπει να με ταΐσεις. Το αγαπημένο μου φαγητό είναι η μπριζόλα
# Σας ευχαριστώ που με χάρατε. Αλλά είναι 13: 05: 02.255000, πρέπει να με ταΐσεις. Το αγαπημένο μου φαγητό είναι η μπριζόλα
# Ευχαριστώ που με χάραξες. Αλλά είναι 13: 05: 02.255000, πρέπει να με τρώτε. Το αγαπημένο μου φαγητό είναι ο τόνος
# Ευχαριστώ που με χάραξες. Αλλά είναι 13: 05: 02.255000, πρέπει να με ταΐσεις. Το αγαπημένο μου φαγητό είναι τα γαλακτοκομικά
# Ευχαριστώ που με χάραξες. Αλλά είναι 13: 05: 02.256000, πρέπει να με τρώτε. Το αγαπημένο μου φαγητό είναι τα γαλακτοκομικά
|
Άλλοι απάντησαν πολύ καλά στις ευρείες πινελιές, οπότε θα ρίξω μερικές λεπτομέρειες.
Οι στοίβες και οι σωροί δεν πρέπει να είναι μοναδικοί. Μια κοινή κατάσταση στην οποία έχετε περισσότερες από μία στοίβες είναι εάν έχετε περισσότερα από ένα νήματα σε μια διαδικασία. Σε αυτήν την περίπτωση κάθε νήμα έχει τη δική του στοίβα. Μπορείτε επίσης να έχετε περισσότερους από έναν σωρούς, για παράδειγμα ορισμένες διαμορφώσεις DLL μπορεί να έχουν ως αποτέλεσμα την εκχώρηση διαφορετικών DLL από διαφορετικούς σωρούς, γι 'αυτό είναι γενικά κακή ιδέα να απελευθερώσετε μνήμη που έχει εκχωρηθεί από διαφορετική βιβλιοθήκη.
Στο C μπορείτε να επωφεληθείτε από την κατανομή μεταβλητού μήκους μέσω της χρήσης του alpha, η οποία κατανέμεται στη στοίβα, σε αντίθεση με την κατανομή, που κατανέμεται στο σωρό. Αυτή η μνήμη δεν θα επιβιώσει από τη δήλωση επιστροφής, αλλά είναι χρήσιμη για ένα μηδενικό buffer
Η δημιουργία ενός τεράστιου προσωρινού buffer στα Windows που δεν χρησιμοποιείτε πολλά δεν είναι δωρεάν. Αυτό συμβαίνει επειδή ο μεταγλωττιστής θα δημιουργήσει έναν βρόχο ανίχνευσης στοίβας που καλείται κάθε φορά που εισάγεται η λειτουργία σας για να βεβαιωθείτε ότι υπάρχει η στοίβα (επειδή τα Windows χρησιμοποιούν μία μόνο σελίδα φύλαξης στο τέλος της στοίβας σας για να εντοπίσουν πότε χρειάζεται να αναπτύξει τη στοίβα. Εάν έχετε πρόσβαση στη μνήμη περισσότερες από μία σελίδες από το τέλος της στοίβας, θα διακόψετε. Παράδειγμα:
άκυρη δυσλειτουργία ()
{
char μεγάλο [10000000];
// Κάνετε κάτι που χρησιμοποιεί μόνο για το πρώτο 1K του 99% του χρόνου.
}
|
Άλλοι απάντησαν άμεσα στην ερώτησή σας, αλλά όταν προσπαθείτε να κατανοήσετε τη στοίβα και το σωρό, νομίζω ότι είναι χρήσιμο να εξετάσετε τη διάταξη μνήμης μιας παραδοσιακής διαδικασίας UNIX (χωρίς νήματα και mmap () με βάση τους κατανεμητές). Η ιστοσελίδα του Memory Management Glossary έχει ένα διάγραμμα αυτής της διάταξης μνήμης.
Η στοίβα και ο σωρός βρίσκονται παραδοσιακά στα αντίθετα άκρα του εικονικού χώρου διευθύνσεων της διαδικασίας. Η στοίβα αυξάνεται αυτόματα όταν έχει πρόσβαση, έως ένα μέγεθος που ορίζεται από τον πυρήνα (το οποίο μπορεί να ρυθμιστεί με το setrlimit (RLIMIT_STACK, ...)). Ο σωρός αυξάνεται όταν ο εκχωρητής μνήμης καλεί την κλήση συστήματος brk () ή sbrk (), χαρτογραφώντας περισσότερες σελίδες φυσικής μνήμης στον εικονικό χώρο διευθύνσεων της διαδικασίας.
Σε συστήματα χωρίς εικονική μνήμη, όπως ορισμένα ενσωματωμένα συστήματα, ισχύει συχνά η ίδια βασική διάταξη, εκτός από το ότι η στοίβα και ο σωρός έχουν σταθερό μέγεθος. Ωστόσο, σε άλλα ενσωματωμένα συστήματα (όπως αυτά που βασίζονται σε μικροελεγκτές Microchip PIC), η στοίβα προγράμματος είναι ένα ξεχωριστό μπλοκ μνήμης που δεν μπορεί να αντιμετωπιστεί με οδηγίες κίνησης δεδομένων και μπορεί να τροποποιηθεί ή να διαβαστεί έμμεσα μόνο μέσω οδηγιών ροής προγράμματος (κλήση, επιστροφή κ.λπ.). Άλλες αρχιτεκτονικές, όπως επεξεργαστές Intel Itanium, έχουν πολλές στοίβες. Υπό αυτήν την έννοια, η στοίβα είναι ένα στοιχείο της αρχιτεκτονικής της CPU.
|
Η στοίβα είναι ένα τμήμαμνήμης που μπορεί να χειριστεί μέσω πολλών βασικών οδηγιών γλώσσας συναρμολόγησης, όπως «pop» (αφαίρεση και επιστροφή τιμής από τη στοίβα) και «push» (ώθηση μιας τιμής στη στοίβα), αλλά και κλήση (καλέστε μια υπορουτίνα - αυτό ωθεί τη διεύθυνση για επιστροφή στη στοίβα) και επιστροφή (επιστροφή από μια υπορουτίνα - αυτό βγάζει τη διεύθυνση από τη στοίβα και μεταβαίνει σε αυτήν). Είναι η περιοχή μνήμης κάτω από το μητρώο δείκτη στοίβας, η οποία μπορεί να ρυθμιστεί ανάλογα με τις ανάγκες. Η στοίβα χρησιμοποιείται επίσης για τη μετάδοση ορισμάτων σε υπορουτίνες και επίσης για τη διατήρηση των τιμών σε καταχωρητές πριν από την κλήση υπορουτίνων.
Ο σωρός είναι ένα μέρος της μνήμης που δίνεται σε μια εφαρμογή από το λειτουργικό σύστημα, συνήθως μέσω ενός συστήματος όπως το malloc. Στα σύγχρονα λειτουργικά συστήματα, αυτή η μνήμη είναι ένα σύνολο σελίδων στις οποίες έχει πρόσβαση μόνο η διαδικασία κλήσης.
Το μέγεθος της στοίβας καθορίζεται κατά το χρόνο εκτέλεσης και γενικά δεν αυξάνεται μετά την έναρξη του προγράμματος. Σε ένα πρόγραμμα C, η στοίβα πρέπει να είναι αρκετά μεγάλη για να διατηρεί κάθε μεταβλητή που δηλώνεται σε κάθε συνάρτηση. Ο σωρός θα αυξηθεί δυναμικά, όπως απαιτείται, αλλά το λειτουργικό σύστημα πραγματοποιεί τελικά την κλήση (συχνά αυξάνεται ο σωρός περισσότερο από την τιμή που ζητάει το malloc, έτσι ώστε τουλάχιστον μερικά μελλοντικά mallocs να μην χρειάζεται να επιστρέψουν στον πυρήνα για να αποκτήστε περισσότερη μνήμη. Αυτή η συμπεριφορά είναι συχνά προσαρμόσιμη)
Επειδή έχετε εκχωρήσει τη στοίβα πριν ξεκινήσετε το πρόγραμμα, δεν χρειάζεται ποτέ να κάνετε malloc για να μπορέσετε να χρησιμοποιήσετε τη στοίβα, έτσι αυτό είναι ένα μικρό πλεονέκτημα εκεί. Στην πράξη, είναι πολύ δύσκολο να προβλεφθεί τι θα είναι γρήγορο και τι θα είναι αργό σε σύγχρονα λειτουργικά συστήματα που έχουν υποσυστήματα εικονικής μνήμης, γιατί ο τρόπος υλοποίησης των σελίδων και πού αποθηκεύονται είναι μια λεπτομέρεια εφαρμογής.
|
Τι είναι μια στοίβα;
Μια στοίβα είναι ένας σωρός αντικειμένων, συνήθως ένας που είναι τακτοποιημένος.
Οι στοίβες στις αρχιτεκτονικές υπολογιστών είναι περιοχές μνήμης όπου τα δεδομένα προστίθενται ή αφαιρούνται με τρόπο τελευταίο σε πρώτο.
Σε μια εφαρμογή πολλαπλών νημάτων, κάθε νήμα θα έχει τη δική του στοίβα.
Τι είναι ο σωρός;
Ένας σωρός είναι μια ακατάστατη συλλογή πραγμάτων που συσσωρεύονται τυχαία.
Στις αρχιτεκτονικές υπολογιστών, ο σωρός είναι μια περιοχή δυναμικής κατανεμημένης μνήμης που διαχειρίζεται αυτόματα από το λειτουργικό σύστημα ή τη βιβλιοθήκη διαχείρισης μνήμης.
Η μνήμη στο σωρό κατανέμεται, απενεργοποιείται και αλλάζει το μέγεθος τακτικά κατά την εκτέλεση του προγράμματος και αυτό μπορεί να οδηγήσει σε ένα πρόβλημα που ονομάζεται κατακερματισμός.
Ο κατακερματισμός εμφανίζεται όταν τα αντικείμενα μνήμης κατανέμονται με μικρά κενά μεταξύ τους που είναι πολύ μικρά για να συγκρατούν επιπλέον αντικείμενα μνήμης.
Το καθαρό αποτέλεσμα είναι ένα ποσοστό του σωρού που δεν μπορεί να χρησιμοποιηθεί για περαιτέρω κατανομές μνήμης.
Και οι δύο μαζί
Σε μια εφαρμογή πολλαπλών νημάτων, κάθε νήμα θα έχει τη δική του στοίβα. Όμως, όλα τα διαφορετικά νήματα θα μοιραστούν το σωρό.
Επειδή τα διαφορετικά νήματα μοιράζονται το σωρό σε μια εφαρμογή πολλαπλών νημάτων, αυτό σημαίνει επίσης ότι πρέπει να υπάρχει κάποιος συντονισμός μεταξύ των νημάτων έτσι ώστε να μην προσπαθούν να έχουν πρόσβαση και να χειριστούν τα ίδια κομμάτια μνήμης στο σωρό στο την ίδια ώρα.
Ποιο είναι πιο γρήγορο - η στοίβα ή ο σωρός; Και γιατί?
Η στοίβα είναι πολύ πιο γρήγορη από το σωρό.
Αυτό οφείλεται στον τρόπο με τον οποίο κατανέμεται η μνήμη στη στοίβα.
Η κατανομή της μνήμης στη στοίβα είναι τόσο απλή όσο η μετακίνηση του δείκτη στοίβας προς τα πάνω.
Για άτομα που είναι νέοι στον προγραμματισμό, ίσως είναι καλή ιδέα να χρησιμοποιήσετε τη στοίβα, καθώς είναι ευκολότερο.
Επειδή η στοίβα είναι μικρή, θα θέλατε να τη χρησιμοποιήσετε όταν γνωρίζετε ακριβώς πόση μνήμη θα χρειαστείτε για τα δεδομένα σας ή εάν γνωρίζετε ότι το μέγεθος των δεδομένων σας είναι πολύ μικρό.
Είναι καλύτερα να χρησιμοποιήσετε το σωρό όταν γνωρίζετε ότι θα χρειαστείτε πολλή μνήμη για τα δεδομένα σας, ή απλά δεν είστε σίγουροι πόση μνήμη θα χρειαστείτε (όπως με μια δυναμική συστοιχία).
Μοντέλο μνήμης Java
Η στοίβα είναι η περιοχή της μνήμης όπου αποθηκεύονται τοπικές μεταβλητές (συμπεριλαμβανομένων των παραμέτρων μεθόδου). Όταν πρόκειται για μεταβλητές αντικειμένων, αυτές είναι απλώς αναφορές (δείκτες) στα πραγματικά αντικείμενα στο σωρό.
Κάθε φορά που ένα αντικείμενο δημιουργείται, ένα κομμάτι μνήμης σωρού τίθεται στην άκρη για να κρατήσει τα δεδομένα (κατάσταση) αυτού του αντικειμένου. Επειδή τα αντικείμενα μπορούν να περιέχουν άλλα αντικείμενα, ορισμένα από αυτά τα δεδομένα μπορούν στην πραγματικότητα να περιέχουν αναφορές σε αυτά τα ένθετα αντικείμενα.
|
Νομίζω ότι πολλοί άλλοι άνθρωποι σας έδωσαν ως επί το πλείστον σωστές απαντήσεις σε αυτό το θέμα.
Μια λεπτομέρεια που έχει χαθεί, ωστόσο, είναι ότι ο "σωρός" θα πρέπει μάλλον να ονομαστεί "δωρεάν κατάστημα" Ο λόγος για αυτήν τη διάκριση είναι ότι το αρχικό δωρεάν κατάστημα εφαρμόστηκε με μια δομή δεδομένων γνωστή ως "διωνυμικός σωρός" Για αυτόν τον λόγο, η κατανομή από τις πρώτες υλοποιήσεις του malloc () / free () ήταν η κατανομή από έναν σωρό. Ωστόσο, σε αυτήν τη σύγχρονη εποχή, τα περισσότερα δωρεάν καταστήματα εφαρμόζονται με πολύ περίπλοκες δομές δεδομένων που δεν είναι διωνυμικοί σωροί.
|
Μπορείτε να κάνετε μερικά ενδιαφέροντα πράγματα με τη στοίβα. Για παράδειγμα, έχετε λειτουργίες όπως το ala (υποθέτοντας ότι μπορείτε να ξεπεράσετε τις άφθονες προειδοποιήσεις σχετικά με τη χρήση του), η οποία είναι μια μορφή malloc πουχρησιμοποιεί συγκεκριμένα τη στοίβα, όχι το σωρό, για τη μνήμη.
Ωστόσο, τα σφάλματα μνήμης που βασίζονται στη στοίβα είναι μερικά από τα χειρότερα που έχω βιώσει. Εάν χρησιμοποιείτε σωστή μνήμη και υπερβείτε τα όρια του κατανεμημένου μπλοκ, έχετε μια πιθανή πιθανότητα να προκαλέσετε σφάλμα τμήματος. (Όχι 100%: το μπλοκ σας μπορεί να είναι τυχαία γειτονικό με ένα άλλο που έχετε εκχωρήσει προηγουμένως.) Αλλά επειδή οι μεταβλητές που δημιουργούνται στη στοίβα είναι πάντα συνεχόμενες μεταξύ τους, η διαγραφή εκτός ορίου μπορεί να αλλάξει την τιμή μιας άλλης μεταβλητής. Έχω μάθει ότι όποτε αισθάνομαι ότι το πρόγραμμά μου έχει σταματήσει να συμμορφώνεται με τους νόμους της λογικής, είναι πιθανώς υπερχείλιση buffer.
|
Απλά, η στοίβα είναι όπου δημιουργούνται τοπικές μεταβλητές. Επίσης, κάθε φορά που καλείτε μια υπορουτίνα του μετρητή προγράμματος (δείκτης στην επόμενη εντολή του μηχανήματος) και τυχόν σημαντικούς καταχωρητές, και μερικές φορές οι παράμετροι ωθούνται στη στοίβα. Στη συνέχεια, τυχόν τοπικές μεταβλητές μέσα στην υπορουτίνα ωθούνται στη στοίβα (και χρησιμοποιούνται από εκεί). Όταν τελειώσει η υπορουτίνα, όλα αυτά ξεπροβάλλουν από τη στοίβα. Ο υπολογιστής και τα δεδομένα εγγραφής παίρνουν και επανατοποθετούν εκεί που ήταν όπως εμφανίστηκε, έτσι ώστε το πρόγραμμά σας να μπορεί να προχωρήσει καλά.
Ο σωρός είναι η περιοχή της μνήμης οι δυναμικές εκχωρήσεις μνήμης γίνονται από (ρητές "νέες" ή "εκχώρηση" κλήσεις). Πρόκειται για μια ειδική δομή δεδομένων που μπορεί να παρακολουθεί μπλοκ μνήμης διαφόρων μεγεθών και την κατάσταση κατανομής τους.
Στα "κλασικά" συστήματα η μνήμη RAM σχεδιάστηκε έτσι ώστε ο δείκτης στοίβας να ξεκινά στο κάτω μέρος της μνήμης, ο δείκτης σωρού να ξεκινά στην κορυφή και να μεγαλώνουν το ένα προς το άλλο. Εάν αλληλεπικαλύπτονται, δεν έχετε μνήμη RAM. Αυτό όμως δεν λειτουργεί με σύγχρονα πολλαπλών νημάτων OS. Κάθε νήμα πρέπει να έχει τη δική του στοίβα και αυτά μπορούν να δημιουργηθούν δυναμικά.
|
Από το WikiAnwser.
Σωρός
Όταν μια συνάρτηση ή μια μέθοδο καλεί μια άλλη συνάρτηση η οποία με τη σειρά της καλεί μια άλλη συνάρτηση κ.λπ., η εκτέλεση όλων αυτών των λειτουργιών παραμένει σε αναστολή έως ότου η τελευταία λειτουργία επιστρέψει την τιμή της.
Αυτή η αλυσίδα των κλήσεων λειτουργίας σε αναστολή είναι η στοίβα, επειδή τα στοιχεία στη στοίβα (λειτουργίες κλήσεων) εξαρτώνται το ένα από το άλλο.
Η στοίβα είναι σημαντικό να ληφθεί υπόψη στον χειρισμό εξαιρέσεων και στις εκτελέσεις νήματος.
Σωρός
Ο σωρός είναι απλά η μνήμη που χρησιμοποιείται από προγράμματα για την αποθήκευση μεταβλητών.
Το στοιχείο του σωρού (μεταβλητές) δεν έχει καμία εξάρτηση μεταξύ τους και μπορεί πάντα να έχει πρόσβαση τυχαία ανά πάσα στιγμή.
|
Σωρός
Πολύ γρήγορη πρόσβαση
Δεν χρειάζεται να καταργήσετε ρητά τις μεταβλητές
Η διαχείριση του χώρου γίνεται αποτελεσματικά από την CPU, η μνήμη δεν θα κατακερματιστεί
Μόνο τοπικές μεταβλητές
Όριο μεγέθους στοίβας (εξαρτάται από το λειτουργικό σύστημα)
Δεν είναι δυνατή η αλλαγή μεγέθους των μεταβλητών
Σωρός
Οι μεταβλητές είναι προσβάσιμες παγκοσμίως
Δεν υπάρχει όριο στο μέγεθος της μνήμης
(Σχετικά) πιο αργή πρόσβαση
Χωρίς εγγυημένη αποτελεσματική χρήση χώρου, η μνήμη μπορεί να κατακερματιστεί με την πάροδο του χρόνου καθώς εκχωρούνται μπλοκ μνήμης και στη συνέχεια απελευθερώνεται
Πρέπει να διαχειριστείτε τη μνήμη (είστε υπεύθυνοι για την κατανομή και την απελευθέρωση μεταβλητών)
Οι μεταβλητές μπορούν να αλλάξουν το μέγεθος χρησιμοποιώντας το realloc ()
|
Εν συντομία
Μια στοίβα χρησιμοποιείται για εκχώρηση στατικής μνήμης και σωρός για δυναμική κατανομή μνήμης, και οι δύο αποθηκευμένες στη μνήμη RAM του υπολογιστή.
Λεπτομερώς
Η στοίβα
Η στοίβα είναι μια δομή δεδομένων "LIFO" (τελευταία, πρώτη έξοδος), η οποία διαχειρίζεται και βελτιστοποιείται από την CPU αρκετά στενά. Κάθε φορά που μια συνάρτηση δηλώνει μια νέα μεταβλητή, "ωθείται" στη στοίβα. Στη συνέχεια, κάθε φορά που κλείνει μια συνάρτηση, απελευθερώνονται όλες οι μεταβλητές που μετακινούνται στη στοίβα από αυτήν τη συνάρτηση (δηλαδή, διαγράφονται). Μόλις ελευθερωθεί μια μεταβλητή στοίβας, αυτή η περιοχή μνήμης καθίσταται διαθέσιμη για άλλες μεταβλητές στοίβας.
Το πλεονέκτημα της χρήσης της στοίβας για την αποθήκευση μεταβλητών, είναι ότι η μνήμη διαχειρίζεται για εσάς. Δεν χρειάζεται να εκχωρήσετε τη μνήμη με το χέρι ή να την ελευθερώσετε όταν δεν την χρειάζεστε πια. Επιπλέον, επειδή η CPU οργανώνει τη μνήμη στοίβας τόσο αποτελεσματικά, η ανάγνωση και η εγγραφή σε μεταβλητές στοίβας είναι πολύ γρήγορη.
Περισσότερα μπορείτε να βρείτε εδώ.
Ο σωρός
Ο σωρός είναι μια περιοχή της μνήμης του υπολογιστή σας που δεν διαχειρίζεται αυτόματα για εσάς και δεν διαχειρίζεται τόσο καλά από τη CPU. Είναι μια πιο ελεύθερη περιοχή μνήμης (και είναι μεγαλύτερη). Για να εκχωρήσετε μνήμη στο σωρό, πρέπει να χρησιμοποιήσετε malloc () ή calloc (), οι οποίες είναι ενσωματωμένες συναρτήσεις C. Μόλις εκχωρήσετε τη μνήμη στο σωρό, είστε υπεύθυνοι για τη χρήση δωρεάν () για να αφαιρέσετε αυτήν τη μνήμη όταν δεν την χρειάζεστε πια.
Εάν δεν το κάνετε αυτό, το πρόγραμμά σας θα έχει αυτό που είναι γνωστό ως διαρροή μνήμης. Δηλαδή, η μνήμη στο σωρό θα παραμείνει στην άκρη (και δεν θα είναι διαθέσιμη σε άλλες διαδικασίες). Όπως θα δούμε στην ενότητα εντοπισμού σφαλμάτων, υπάρχει ένα εργαλείο που ονομάζεται Valgrind που μπορεί να σας βοηθήσει να εντοπίσετε διαρροές μνήμης.
Σε αντίθεση με τη στοίβα, ο σωρός δεν έχει περιορισμούς μεγέθους σε μεταβλητό μέγεθος (εκτός από τους προφανείς φυσικούς περιορισμούς του υπολογιστή σας). Η μνήμη του σωρού είναι ελαφρώς πιο αργή για να διαβαστεί και να γραφτεί, γιατί πρέπει να χρησιμοποιήσετε δείκτες για πρόσβαση στη μνήμη στο σωρό. Θα μιλήσουμε σύντομα για δείκτες.
Σε αντίθεση με τη στοίβα,Οι μεταβλητές που δημιουργούνται στο σωρό είναι προσβάσιμες από οποιαδήποτε λειτουργία, οπουδήποτε στο πρόγραμμά σας. Οι μεταβλητές σωρού είναι ουσιαστικά παγκόσμιες.
Περισσότερα μπορείτε να βρείτε εδώ.
Οι μεταβλητές που κατανέμονται στη στοίβα αποθηκεύονται απευθείας στη μνήμη και η πρόσβαση σε αυτήν τη μνήμη είναι πολύ γρήγορη και η κατανομή της αντιμετωπίζεται κατά τη σύνταξη του προγράμματος. Όταν μια συνάρτηση ή μια μέθοδο καλεί μια άλλη συνάρτηση η οποία με τη σειρά της καλεί μια άλλη συνάρτηση κ.λπ., η εκτέλεση όλων αυτών των λειτουργιών παραμένει σε αναστολή έως ότου η τελευταία λειτουργία επιστρέψει την τιμή της. Η στοίβα διατηρείται πάντα με σειρά LIFO, το πιο πρόσφατα δεσμευμένο μπλοκ είναι πάντα το επόμενο μπλοκ που θα απελευθερωθεί. Αυτό καθιστά πραγματικά απλό να παρακολουθείτε τη στοίβα, η απελευθέρωση ενός μπλοκ από τη στοίβα δεν είναι τίποτα περισσότερο από την προσαρμογή ενός δείκτη.
Οι μεταβλητές που έχουν εκχωρηθεί στο σωρό έχουν τη μνήμη τους εκχωρημένη κατά το χρόνο εκτέλεσης και η πρόσβαση σε αυτήν τη μνήμη είναι λίγο πιο αργή, αλλά το μέγεθος του σωρού περιορίζεται μόνο από το μέγεθος της εικονικής μνήμης. Τα στοιχεία του σωρού δεν έχουν καμία εξάρτηση μεταξύ τους και μπορούν πάντα να έχουν πρόσβαση τυχαία ανά πάσα στιγμή. Μπορείτε να εκχωρήσετε ένα μπλοκ ανά πάσα στιγμή και να το ελευθερώσετε ανά πάσα στιγμή. Αυτό καθιστά πολύ πιο περίπλοκο να παρακολουθείτε ποια μέρη του σωρού κατανέμονται ή δωρεάν ανά πάσα στιγμή.
Μπορείτε να χρησιμοποιήσετε τη στοίβα εάν γνωρίζετε ακριβώς πόσα δεδομένα πρέπει να διαθέσετε πριν από τη μεταγλώττιση και δεν είναι πολύ μεγάλο. Μπορείτε να χρησιμοποιήσετε το σωρό εάν δεν γνωρίζετε ακριβώς πόσα δεδομένα θα χρειαστείτε κατά το χρόνο εκτέλεσης ή εάν πρέπει να διαθέσετε πολλά δεδομένα.
Σε μια κατάσταση πολλαπλών νημάτων, κάθε νήμα θα έχει τη δική του εντελώς ανεξάρτητη στοίβα, αλλά θα μοιράζεται το σωρό. Η στοίβα είναι συγκεκριμένη για το νήμα και ο σωρός είναι συγκεκριμένος για την εφαρμογή. Η στοίβα είναι σημαντικό να ληφθεί υπόψη στον χειρισμό εξαιρέσεων και στις εκτελέσεις νήματος.
Κάθε νήμα παίρνει μια στοίβα, ενώ συνήθως υπάρχει μόνο ένας σωρός για την εφαρμογή (αν και δεν είναι ασυνήθιστο να υπάρχουν πολλοί σωροί για διαφορετικούς τύπους κατανομής).
Κατά το χρόνο εκτέλεσης, εάν η εφαρμογή χρειάζεται περισσότερο σωρό, μπορεί να εκχωρήσει μνήμη από ελεύθερη μνήμη και εάν η στοίβα χρειάζεται μνήμη, μπορεί να εκχωρήσει μνήμη από ελεύθερη μνήμη που έχει εκχωρηθεί για την εφαρμογή.
Ακόμα, περισσότερες λεπτομέρειες δίνονται εδώ και εδώ.
Τώρα έλα στις απαντήσεις της ερώτησής σας.
Σε ποιο βαθμό ελέγχονται από το λειτουργικό σύστημα ή το χρόνο εκτέλεσης της γλώσσας;
Το λειτουργικό σύστημα εκχωρεί τη στοίβα για κάθε νήμα επιπέδου συστήματος κατά τη δημιουργία του νήματος. Συνήθως, το λειτουργικό σύστημα καλείται από τον χρόνο εκτέλεσης της γλώσσας για να εκχωρήσει το σωρό για την εφαρμογή.
Περισσότερα μπορείτε να βρείτε εδώ.
Ποιο είναι το πεδίο εφαρμογής τους;
Έχει ήδη δοθεί στην κορυφή.
"Μπορείτε να χρησιμοποιήσετε τη στοίβα αν γνωρίζετε ακριβώς πόσα δεδομένα πρέπει να διαθέσετε πριν από τη μεταγλώττιση και δεν είναι πολύ μεγάλο. Μπορείτε να χρησιμοποιήσετε το σωρό αν δεν γνωρίζετε ακριβώς πόσα δεδομένα θα χρειαστείτε κατά την εκτέλεση ή πρέπει να διαθέσετε πολλά δεδομένα. "
Περισσότερα μπορείτε να βρείτε εδώ.
Τι καθορίζει το μέγεθος καθενός από αυτά;
Το μέγεθος της στοίβας ορίζεται από το λειτουργικό σύστημα όταν δημιουργείται ένα νήμα. Το μέγεθος του σωρού έχει οριστεί κατά την εκκίνηση της εφαρμογής, αλλά μπορεί να αυξηθεί καθώς απαιτείται χώρος (ο εκχωρητής ζητά περισσότερη μνήμη από το λειτουργικό σύστημα).
Τι κάνει πιο γρήγορο;
Η κατανομή στοίβας είναι πολύ πιο γρήγορη, καθώς το μόνο που κάνει είναι να μετακινήσετε το δείκτη στοίβας. Χρησιμοποιώντας ομάδες μνήμης, μπορείτε να έχετε συγκρίσιμη απόδοση από την κατανομή σωρών, αλλά αυτό έρχεται με μια ελαφριά πρόσθετη πολυπλοκότητα και τους δικούς του πονοκεφάλους.
Επίσης, η στοίβα εναντίον του σωρού δεν είναι μόνο ζήτημα απόδοσης. σας λέει επίσης πολλά για την αναμενόμενη διάρκεια ζωής των αντικειμένων.
Λεπτομέρειες μπορείτε να βρείτε από εδώ.
|
Εντάξει, απλά και με λίγα λόγια, σημαίνουν παραγγελία και όχι παραγγελία ...!
Στοίβα: Σε αντικείμενα στοίβας, τα πράγματα έρχονται το ένα πάνω στο άλλο, σημαίνει ότι θα γίνουν ταχύτερα και πιο αποτελεσματικά για επεξεργασία! ...
Υπάρχει λοιπόν πάντα ένας δείκτης που δείχνει το συγκεκριμένο αντικείμενο, ενώ η επεξεργασία θα είναι ταχύτερη, υπάρχει επίσης σχέση μεταξύ των αντικειμένων! ...
Σωρός: Χωρίς παραγγελία, η επεξεργασία θα είναι πιο αργή και οι τιμές μπερδεύονται μαζί με καμία συγκεκριμένη παραγγελία ή ευρετήριο ... υπάρχουν τυχαίες και δεν υπάρχει σχέση μεταξύ τους ... οπότε η εκτέλεση και ο χρόνος χρήσης θα μπορούσαν να διαφέρουν ...
Δημιουργώ επίσης την παρακάτω εικόνα για να δείξω πώς μοιάζουν:
|
στοίβα, σωρός και δεδομένα κάθε διαδικασίας σε εικονική μνήμη:
|
Τη δεκαετία του 1980, το UNIX διαδόθηκε σαν λαγουδάκια με μεγάλες εταιρείες να κυλούν δικές τους.
Η Exxon είχε ένα όπως έχασε δεκάδες επωνυμίες από την ιστορία.
Το πώς ορίστηκε η μνήμη ήταν στη διακριτική ευχέρεια των πολλών εφαρμογών.
Ένα τυπικό πρόγραμμα C ήταν απλό στη μνήμη με
μια ευκαιρία να αυξηθεί αλλάζοντας την τιμή brk ().
Συνήθως, το HEAP ήταν ακριβώς κάτω από αυτήν την τιμή brk
και η αύξηση brk αύξησε την ποσότητα του διαθέσιμου σωρού.
Το ενιαίο STACK ήταν συνήθως μια περιοχή κάτω από το HEAP που ήταν ένα κομμάτι μνήμης
δεν περιέχει τίποτα αξίας μέχρι την κορυφή του επόμενου σταθερού μπλοκ μνήμης.
Αυτό το επόμενο μπλοκ ήταν συχνά CODE που θα μπορούσε να αντικατασταθεί από δεδομένα στοίβας
σε μια από τις διάσημες αμυχές της εποχής της.
Ένα τυπικό μπλοκ μνήμης ήταν το BSS (ένα μηδέναξίες)
που τυχαία δεν μηδενίστηκε σε προσφορά ενός κατασκευαστή.
Ένα άλλο ήταν τα DATA που περιείχαν αρχικοποιημένες τιμές, συμπεριλαμβανομένων των συμβολοσειρών και των αριθμών.
Ένα τρίτο ήταν το CODE που περιέχει CRT (C runtime), main, συναρτήσεις και βιβλιοθήκες.
Η εμφάνιση της εικονικής μνήμης στο UNIX αλλάζει πολλούς από τους περιορισμούς.
Δεν υπάρχει αντικειμενικός λόγος για τον οποίο αυτά τα μπλοκ πρέπει να είναι συνεχόμενα,
ή σταθερό σε μέγεθος, ή παραγγέλνω έναν συγκεκριμένο τρόπο τώρα.
Φυσικά, πριν από το UNIX ήταν Multics που δεν υπέφεραν από αυτούς τους περιορισμούς.
Εδώ είναι ένα σχηματικό που δείχνει μια από τις διατάξεις μνήμης αυτής της εποχής.
|
Μερικά λεπτά: Νομίζω, θα ήταν καλό να σχεδιάσετε γραφικά και πιο απλή μνήμη:
Βέλη - δείξτε πού αναπτύσσονται στοίβα και σωρός, το μέγεθος στοίβας διεργασίας έχει όριο, ορίζεται στο λειτουργικό σύστημα, τα όρια μεγέθους στοίβας νήματος με παραμέτρους στο νήμα δημιουργούν API Ο σωρός συνήθως περιορίζει από τη διαδικασία το μέγιστο μέγεθος εικονικής μνήμης, για 32 bit 2-4 GB για παράδειγμα.
Τόσο απλός τρόπος: ο σωρός της διαδικασίας είναι γενικός για τη διαδικασία και όλα τα νήματα μέσα, χρησιμοποιώντας για κατανομή μνήμης σε κοινή περίπτωση με κάτι σαν malloc ().
Η στοίβα είναι γρήγορη μνήμη για αποθήκευση σε συνήθη δείκτες επιστροφής λειτουργίας και μεταβλητές, που υποβάλλονται σε επεξεργασία ως παράμετροι στην κλήση συνάρτησης, μεταβλητές τοπικής συνάρτησης.
|
Δεδομένου ότι κάποιες απαντήσεις πήγαιναν, θα συνεισφέρω τα ακάρεά μου.
Παραδόξως, κανείς δεν ανέφερε ότι πολλές στοίβες κλήσεων (δηλαδή που δεν σχετίζονται με τον αριθμό των νημάτων σε λειτουργία OS) βρίσκονται όχι μόνο σε εξωτικές γλώσσες (PostScript) ή πλατφόρμες (Intel Itanium), αλλά και σε ίνες, πράσινα νήματα και κάποιες εφαρμογές κορουτινών.
Οι ίνες, τα πράσινα νήματα και οι κορουτίνες είναι από πολλές απόψεις παρόμοιες, γεγονός που οδηγεί σε μεγάλη σύγχυση. Η διαφορά μεταξύ των ινών και των πράσινων νημάτων είναι ότι το πρώτο χρησιμοποιεί συνεταιριστικό πολλαπλών εργασιών, ενώ το δεύτερο μπορεί να διαθέτει είτε συνεργατικό είτε προληπτικό (ή ακόμη και τα δύο). Για τη διάκριση μεταξύ ινών και κορουτίνων, δείτε εδώ.
Σε κάθε περίπτωση, ο σκοπός και των δύο ινών, των πράσινων νημάτων και των κορουτινών είναι η εκτέλεση πολλαπλών λειτουργιών ταυτόχρονα, αλλά όχι παράλληλα (δείτε αυτήν την ερώτηση SO για τη διάκριση) μέσα σε ένα μόνο νήμα επιπέδου OS, μεταφέροντας τον έλεγχο εμπρός και πίσω με οργανωμένο τρόπο.
Όταν χρησιμοποιείτε ίνες, πράσινα νήματα ή κορουτίνες, συνήθως έχετε μια ξεχωριστή στοίβα ανά λειτουργία. (Τεχνικά, όχι μόνο μια στοίβα αλλά ένα ολόκληρο πλαίσιο εκτέλεσης είναι ανά λειτουργία. Το πιο σημαντικό, οι καταχωρητές της CPU.) Για κάθε νήμα υπάρχουν τόσες στοίβες όσο λειτουργούν ταυτόχρονα και το νήμα αλλάζει μεταξύ εκτέλεσης κάθε λειτουργίας σύμφωνα με τη λογική του προγράμματος σας. Όταν μια συνάρτηση εκτελείται στο τέλος της, η στοίβα της καταστρέφεται. Έτσι, ο αριθμός και η διάρκεια ζωής των στοιβών είναι δυναμικές και δεν καθορίζονται από τον αριθμό των νημάτων επιπέδου OS!
Σημειώστε ότι είπα "συνήθως έχουν ξεχωριστή στοίβα ανά συνάρτηση". Υπάρχουν τόσο στοιχειώδεις όσο και στοίβες υλοποιήσεις των μαθημάτων. Οι πιο αξιοσημείωτες στοιχειώδεις εφαρμογές C ++ είναι το Boost.Coroutine και το Microsoft PPL's ​​async / waiting. (Ωστόσο, οι επαναλαμβανόμενες συναρτήσεις του C ++ (π.χ. "async and waiting"), οι οποίες προτάθηκαν στο C ++ 17, είναι πιθανό να χρησιμοποιούν σωρουτίνες χωρίς στοίβα.)
Η πρόταση Fibers στην τυπική βιβλιοθήκη C ++ είναι προσεκτική. Επίσης, υπάρχουν κάποιες βιβλιοθήκες τρίτων. Τα πράσινα νήματα είναι εξαιρετικά δημοφιλή σε γλώσσες όπως Python και Ruby.
|
Έχω κάτι να μοιραστώ, αν και τα κύρια σημεία καλύπτονται ήδη.
Σωρός
Πολύ γρήγορη πρόσβαση.
Αποθηκεύτηκε σε RAM.
Οι κλήσεις λειτουργιών φορτώνονται εδώ μαζί με τις τοπικές μεταβλητές και τις παραμέτρους λειτουργίας που έχουν περάσει.
Ο χώρος απελευθερώνεται αυτόματα όταν το πρόγραμμα δεν λειτουργεί.
Αποθηκεύτηκε σε διαδοχική μνήμη.
Σωρός
Αργή πρόσβαση συγκριτικά με το Stack.
Αποθηκεύτηκε σε RAM.
Οι δυναμικά δημιουργημένες μεταβλητές αποθηκεύονται εδώ, κάτι που αργότερα απαιτεί την απελευθέρωση της εκχωρημένης μνήμης μετά τη χρήση.
Αποθηκεύεται όπου γίνεται η κατανομή μνήμης, πάντα προσπελάσιμη από το δείκτη.
Ενδιαφέρουσα σημείωση:
Εάν οι κλήσεις συνάρτησης είχαν αποθηκευτεί σε σωρό, θα είχε ως αποτέλεσμα 2 ακατάστατα σημεία:
Λόγω της διαδοχικής αποθήκευσης στη στοίβα, η εκτέλεση είναι ταχύτερη. Η αποθήκευση στο σωρό θα είχε ως αποτέλεσμα τεράστια κατανάλωση χρόνου, κάνοντας το όλο πρόγραμμα να εκτελεστεί πιο αργό.
Εάν οι συναρτήσεις αποθηκεύονταν σε σωρό (ακατάστατη αποθήκευση με δείκτη), δεν θα υπήρχε τρόπος να επιστρέψετε στη διεύθυνση του καλούντος (που δίνει η στοίβα λόγω διαδοχικής αποθήκευσης στη μνήμη).
|
Ουάου! Τόσες πολλές απαντήσεις και δεν νομίζω ότι μία από αυτές τα πήρε σωστά ...
1) Πού και τι είναι (φυσικά στη μνήμη ενός πραγματικού υπολογιστή);
Η στοίβα είναι μνήμη που ξεκινά ως η υψηλότερη διεύθυνση μνήμης που έχει εκχωρηθεί στην εικόνα του προγράμματος σας και στη συνέχεια μειώνεται η αξία από εκεί. Διατηρείται για τις παραμέτρους των συνθηκών που ονομάζονται και για όλες τις προσωρινές μεταβλητές που χρησιμοποιούνται σε συναρτήσεις.
Υπάρχουν δύο σωροί: δημόσιοι και ιδιωτικοί.
Το ιδιωτικό σωρό ξεκινά σε όριο 16 byte (για προγράμματα 64 bit) ή όριο 8 byte (για προγράμματα 32 bit) μετά το τελευταίο byte κώδικα στο πρόγραμμά σας και, στη συνέχεια,αξία από εκεί. Ονομάζεται επίσης ο προεπιλεγμένος σωρός.
Εάν ο ιδιωτικός σωρός γίνει πολύ μεγάλος, θα επικαλύπτει την περιοχή στοίβας, όπως και η στοίβα επικάλυψη του σωρού εάν γίνει πολύ μεγάλη. Επειδή η στοίβα ξεκινά από μια υψηλότερη διεύθυνση και λειτουργεί μέχρι τη χαμηλότερη διεύθυνση, με σωστή εισβολή μπορείτε να κάνετε τη στοίβα τόσο μεγάλη που θα ξεπεράσει την ιδιωτική περιοχή σωρού και θα επικαλύπτει την περιοχή κώδικα. Το κόλπο είναι τότε να επικαλύπτετε αρκετά από την περιοχή κώδικα που μπορείτε να συνδέσετε με τον κώδικα. Είναι λίγο δύσκολο να το κάνετε και διακινδυνεύετε ένα σφάλμα προγράμματος, αλλά είναι εύκολο και πολύ αποτελεσματικό.
Ο δημόσιος σωρός βρίσκεται στον δικό του χώρο μνήμης εκτός του χώρου εικόνας του προγράμματος. Αυτή η μνήμη θα αποσυμπιεστεί στον σκληρό δίσκο εάν οι πόροι μνήμης σπανίζουν.
2) Σε ποιο βαθμό ελέγχονται από το λειτουργικό σύστημα ή το χρόνο εκτέλεσης της γλώσσας;
Η στοίβα ελέγχεται από τον προγραμματιστή, ο ιδιωτικός σωρός διαχειρίζεται το λειτουργικό σύστημα και ο δημόσιος σωρός δεν ελέγχεται από κανέναν, επειδή είναι υπηρεσία OS - κάνετε αιτήματα και είτε χορηγούνται είτε απορρίπτονται.
2β) Ποιο είναι το πεδίο εφαρμογής τους;
Είναι όλα παγκόσμια για το πρόγραμμα, αλλά το περιεχόμενό τους μπορεί να είναι ιδιωτικό, δημόσιο ή παγκόσμιο.
2γ) Τι καθορίζει το μέγεθος καθενός από αυτά;
Το μέγεθος της στοίβας και ο ιδιωτικός σωρός καθορίζονται από τις επιλογές χρόνου εκτέλεσης του μεταγλωττιστή σας. Ο δημόσιος σωρός αρχικοποιείται κατά το χρόνο εκτέλεσης χρησιμοποιώντας μια παράμετρο μεγέθους.
2δ) Τι κάνει πιο γρήγορο;
Δεν έχουν σχεδιαστεί για να είναι γρήγορες, έχουν σχεδιαστεί για να είναι χρήσιμες. Πώς τα χρησιμοποιεί ο προγραμματιστής καθορίζει εάν είναι "γρήγορο" ή "αργό"
ΠΡΟΣΦΟΡΑ:
https://norasandler.com/2019/02/18/Write-a-Compiler-10.html
https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-getprocessheap
https://docs.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapcreate
|
Πολλές απαντήσεις είναι σωστές ως έννοιες, αλλά πρέπει να σημειώσουμε ότι απαιτείται μια στοίβα από το υλικό (δηλ. Μικροεπεξεργαστής) για να επιτρέπεται η κλήση υπορουτίνων (CALL σε γλώσσα συναρμολόγησης ..). (OOP παιδιά θα το ονομάσουν μεθόδους)
Στη στοίβα αποθηκεύετε διευθύνσεις επιστροφής και η κλήση → push / ret → pop διαχειρίζεται απευθείας σε υλικό.
Μπορείτε να χρησιμοποιήσετε τη στοίβα για να περάσετε παραμέτρους .. ακόμα κι αν είναι πιο αργή από τη χρήση καταχωρητών (θα έλεγε ένας γκουρού μικροεπεξεργαστή ή ένα καλό βιβλίο BIOS της δεκαετίας του 1980 ...)
Χωρίς στοίβα δεν μπορεί να λειτουργήσει μικροεπεξεργαστής. (δεν μπορούμε να φανταστούμε ένα πρόγραμμα, ακόμη και σε γλώσσα συναρμολόγησης, χωρίς υπορουτίνες / λειτουργίες)
Χωρίς το σωρό μπορεί. (Ένα πρόγραμμα γλώσσας συναρμολόγησης μπορεί να λειτουργήσει χωρίς, καθώς ο σωρός είναι μια έννοια OS, όπως malloc, δηλαδή μια κλήση OS / Lib
Η χρήση στοίβας είναι ταχύτερη όπως:
Είναι υλικό και ακόμη και το push / pop είναι πολύ αποδοτικό.
Το malloc απαιτεί την είσοδο σε λειτουργία πυρήνα, χρήση κλειδώματος / semaphore (ή άλλων πρωτότυπων συγχρονισμού) εκτελώντας κάποιο κώδικα και διαχείριση ορισμένων δομών που απαιτούνται για την παρακολούθηση της κατανομής.
|
Το Heap είναι μια περιοχή δυναμικής εκχώρησης μνήμης που διαχειρίζεται αυτόματα από το λειτουργικό σύστημα ή τη βιβλιοθήκη διαχείρισης μνήμης. Μπορείτε να εκχωρήσετε ένα μπλοκ ανά πάσα στιγμή και να το ελευθερώσετε ανά πάσα στιγμή. Η κατανομή σωρού απαιτεί τη διατήρηση μιας πλήρους εγγραφής για το τι εκχωρείται η μνήμη και τι δεν είναι, καθώς και κάποια γενική συντήρηση για τη μείωση του κατακερματισμού, βρείτε τμήματα συνεχόμενης μνήμης αρκετά μεγάλα για να ταιριάζουν στο απαιτούμενο μέγεθος κ.ο.κ. Η μνήμη μπορεί να αφαιρεθεί ανά πάσα στιγμή αφήνοντας ελεύθερο χώρο. Καθώς ο σωρός μεγαλώνει, νέα μπλοκ κατανέμονται συχνά από χαμηλότερες διευθύνσεις σε υψηλότερες διευθύνσεις. Έτσι μπορείτε να σκεφτείτε το σωρό ως σωρό μπλοκ μνήμης που μεγαλώνει σε μέγεθος καθώς κατανέμεται η μνήμη. Εάν ο σωρός είναι πολύ μικρός για κατανομή, το μέγεθος μπορεί συχνά να αυξηθεί αποκτώντας περισσότερη μνήμη από το υποκείμενο λειτουργικό σύστημα. Η μνήμη που εκχωρείται από το σωρό θα παραμείνει κατανεμημένη έως ότου συμβεί ένα από τα ακόλουθα:
Η μνήμη ελευθερώνεται
Το πρόγραμμα τερματίζεται
Σωρός:
Αποθηκεύτηκε στη μνήμη RAM του υπολογιστή όπως και ο σωρός.
Οι μεταβλητές που δημιουργούνται στη στοίβα δεν θα καλύπτονται και θα καταργούνται αυτόματα.
Πολύ πιο γρήγορα για κατανομή σε σύγκριση με μεταβλητές στο σωρό.
Αποθηκεύει τοπικά δεδομένα, διευθύνσεις επιστροφής, που χρησιμοποιούνται για τη διαβίβαση παραμέτρων.
Μπορεί να έχει υπερχείλιση στοίβας όταν χρησιμοποιείται πολύ μεγάλο μέρος της στοίβας (κυρίως
από άπειρη ή πολύ βαθιά αναδρομή, πολύ μεγάλες κατανομές).
Θα χρησιμοποιούσατε τη στοίβα εάν γνωρίζετε ακριβώς πόσα δεδομένα χρειάζεστε
διαθέστε πριν από τη μεταγλώττιση και δεν είναι πολύ μεγάλο.
Συνήθως έχει ήδη καθοριστεί ένα μέγιστο μέγεθος όταν το πρόγραμμά σας
ξεκινά.
Σωρός:
Αποθηκεύτηκε στη μνήμη RAM του υπολογιστή όπως και η στοίβα.
Στο C ++, οι μεταβλητές στο σωρό πρέπει να καταστρέφονται χειροκίνητα και ποτέ
δεν εμπίπτουν στο πεδίο εφαρμογής.
Τα δεδομένα απελευθερώνονται με διαγραφή, διαγραφή [] ή δωρεάν.
Αργότερη κατανομή σε σύγκριση με μεταβλητές στη στοίβα.
Χρησιμοποιείται κατ 'απαίτηση για εκχώρηση ενός μπλοκ δεδομένων για χρήση από το πρόγραμμα.
Μπορεί να έχει κατακερματισμό όταν υπάρχουν πολλές κατανομές και
απαλλαγές.
Στο C ++ ή C, τα δεδομένα που δημιουργούνται στο σωρό θα επισημαίνονται από δείκτες
και κατανέμεται με νέο ή malloc αντίστοιχα.
Μπορεί να έχει αποτυχίες κατανομής εάν ζητηθεί πολύ μεγάλο από ένα buffer
κατανέμεται.
Εσύθα χρησιμοποιούσε το σωρό εάν δεν ξέρετε ακριβώς πόσα δεδομένα εσείς
θα χρειαστεί κατά το χρόνο εκτέλεσης ή εάν πρέπει να διαθέσετε πολλά δεδομένα
Υπεύθυνος για διαρροές μνήμης.
|
Η στοίβα είναι ουσιαστικά μια εύκολη στην πρόσβαση μνήμη που διαχειρίζεται απλά τα στοιχεία της
ως - καλά - στοίβα. Μόνο αντικείμενα για τα οποία το μέγεθος είναι γνωστό εκ των προτέρων μπορούν να πάνε στη στοίβα. Αυτό ισχύει για αριθμούς, χορδές, μπολ.
Ο σωρός είναι μια μνήμη για στοιχεία των οποίων δεν μπορείτε να προκαθορίσετε το
ακριβές μέγεθος και δομή. Δεδομένου ότι τα αντικείμενα και οι πίνακες μπορούν να μεταλλαχθούν και
αλλάξτε κατά το χρόνο εκτέλεσης, πρέπει να μπουν στο σωρό.
Πηγή: Academind
|
Η στοίβα και ο σωρός της CPU σχετίζονται φυσικά με τον τρόπο λειτουργίας της CPU και των καταχωρητών με τη μνήμη, τον τρόπο λειτουργίας της γλώσσας συναρμολόγησης μηχανών, όχι με τις γλώσσες υψηλού επιπέδου, ακόμα και αν αυτές οι γλώσσες μπορούν να αποφασίσουν μικρά πράγματα.
Όλες οι σύγχρονες CPU λειτουργούν με την "ίδια" θεωρία μικροεπεξεργαστών: βασίζονται σε αυτό που ονομάζεται "καταχωρητές" και ορισμένοι προορίζονται για "στοίβα" για να αποκτήσουν απόδοση. Όλες οι CPU έχουν καταχωρητές στοίβας από την αρχή και ήταν πάντα εδώ, τρόπος ομιλίας, όπως ξέρω. Οι γλώσσες συναρμολόγησης είναι οι ίδιες από την αρχή, παρά τις παραλλαγές ... έως τη Microsoft και την Ενδιάμεση Γλώσσα (IL) που άλλαξαν το παράδειγμα για να έχουν μια γλώσσα συναρμολόγησης εικονικής μηχανής OO. Έτσι θα είμαστε σε θέση να έχουμε κάποια CPU CLI / CIL στο μέλλον (ένα έργο MS).
Οι CPU έχουν καταχωρητές στοίβας για να επιταχύνουν την πρόσβαση σε μνήμες, αλλά είναι περιορισμένοι σε σύγκριση με τη χρήση άλλων καταχωρητών για πλήρη πρόσβαση σε όλη τη διαθέσιμη μνήμη για τον επεξεργαστή. Για αυτό μιλήσαμε για κατανομές στοίβας και σωρού.
Συνοπτικά, και γενικά, ο σωρός είναι hudge και αργός και προορίζεται για "παγκόσμιες" περιπτώσεις και περιεχόμενο αντικειμένων, καθώς η στοίβα είναι μικρή και γρήγορη και για "τοπικές" μεταβλητές και αναφορές (κρυμμένοι δείκτες που πρέπει να ξεχάσετε να τις διαχειριστείτε).
Έτσι, όταν χρησιμοποιούμε τη νέα λέξη-κλειδί σε μια μέθοδο, η αναφορά (ένα int) δημιουργείται στη στοίβα, αλλά το αντικείμενο και όλο το περιεχόμενό του (τύποι τιμών καθώς και αντικείμενα) δημιουργείται στο σωρό, αν θυμάμαι. Όμως, τοπικοί στοιχειώδεις τύποι τιμών και πίνακες δημιουργούνται στη στοίβα.
Η διαφορά στην πρόσβαση στη μνήμη είναι στο επίπεδο αναφοράς των κελιών: η αντιμετώπιση του σωρού, η συνολική μνήμη της διαδικασίας, απαιτεί περισσότερη πολυπλοκότητα όσον αφορά το χειρισμό των καταχωρητών CPU, από τη στοίβα που είναι "περισσότερο" τοπικά όσον αφορά την αντιμετώπιση επειδή η στοίβα CPU Το μητρώο χρησιμοποιείται ως διεύθυνση βάσης, αν θυμάμαι.
Γι 'αυτό όταν έχουμε πολύ μεγάλες ή άπειρες επαναλαμβανόμενες κλήσεις ή βρόχους, έχουμε υπερχείλιση στοίβας γρήγορα, χωρίς να παγώσουμε το σύστημα σε σύγχρονους υπολογιστές ...
C # Heap (ing) Vs Stack (ing) In .NET
Stack vs Heap: Μάθετε τη διαφορά
Κατανομή μνήμης στατικής τάξης όπου αποθηκεύεται C #
Τι και πού είναι η στοίβα και ο σωρός;
https://en.wikipedia.org/wiki/Memory_management
https://en.wikipedia.org/wiki/Stack_register
Πόροι γλώσσας συναρμολόγησης:
Εκπαιδευτικό πρόγραμμα συναρμολόγησης
Εγχειρίδια προγραμματιστών λογισμικού Intel® 64 και IA-32
|
Σας ευχαριστώ για μια πολύ καλή συζήτηση, αλλά ως πραγματικός noob αναρωτιέμαι πού φυλάσσονται οι οδηγίες; Στην αρχή, οι επιστήμονες αποφάσισαν μεταξύ δύο αρχιτεκτονικών (von NEUMANN, όπου όλα θεωρούνται DATA και HARVARD όπου μια περιοχή μνήμης προοριζόταν για οδηγίες και μια άλλη για δεδομένα). Τελικά, πήγαμε με το σχέδιο von Neumann και τώρα όλα θεωρούνται «τα ίδια». Αυτό δυσκολεύτηκε για μένα όταν έμαθα συναρμολόγηση
https://www.cs.virginia.edu/~evans/cs216/guides/x86.html
γιατί μιλούν για καταχωρητές και δείκτες στοίβας.
Όλα τα παραπάνω μιλούν για DATA. Υποθέτω ότι επειδή μια οδηγία είναι ένα καθορισμένο πράγμα με ένα συγκεκριμένο αποτύπωμα μνήμης, θα πήγαινε στη στοίβα και έτσι όλοι οι καταχωρητές «αυτών» που συζητήθηκαν στη συναρμολόγηση βρίσκονται στη στοίβα. Φυσικά, τότε ήρθε αντικειμενοστρεφής προγραμματισμός με οδηγίες και δεδομένα που έρχονται σε μια δομή που ήταν δυναμική, οπότε τώρα οι οδηγίες θα διατηρηθούν επίσης στο σωρό;
|
Πολύ ενεργή ερώτηση. Κερδίστε 10 φήμη για να απαντήσετε σε αυτήν την ερώτηση. Η απαίτηση φήμης συμβάλλει στην προστασία αυτής της ερώτησης από ανεπιθύμητες ενέργειες και μη απαντήσεις.
Δεν είναι η απάντηση που ψάχνετε; Περιηγηθείτε σε άλλες ερωτήσεις με ετικέτα διαχείριση μνήμης στοίβα γλώσσα-αγνωστικός σωρός δυναμική κατανομή μνήμης ή κάντε τη δική σας ερώτηση.